package com.gss.armory.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthoritiesContainer;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.webflow.execution.RequestContext;

import com.gss.armory.domain.CompanyDetailsDTO;
import com.gss.armory.domain.DocAttDTO;
import com.gss.armory.domain.DocGeneralDetailsDTO;
import com.gss.armory.domain.DocGeneralDetailsDTO.DocumentFlowStatus;
import com.gss.armory.domain.DocReviewerApproverForWFDTO;
import com.gss.armory.domain.DocumentAuthSignatoryDTO;
import com.gss.armory.domain.DocumentCategoryDTO;
import com.gss.armory.domain.DocumentCustodianDetailsDTO;
import com.gss.armory.domain.DocumentLinkDTO;
import com.gss.armory.domain.DocumentLinkDTO.DocLinkType;
import com.gss.armory.domain.DocumentMetadataValueDTO;
import com.gss.armory.domain.DocumentWorkflowDetailsDTO;
import com.gss.armory.domain.DocumentWorkflowDetailsDTO.WorkflowEventStatus;
import com.gss.armory.domain.UserActivityGroup;
import com.gss.armory.domain.UserActivityGroup.DocActivityType;
import com.gss.armory.form.DocDetailsForm;
import com.gss.armory.form.DocMetaDataAttrForm;
import com.gss.armory.form.DocRenewalDetailsForm;
import com.gss.armory.form.DocumentCustodianDetailsForm;
import com.gss.armory.form.UserSearchForm;
import com.gss.armory.persistence.CommonDAO;
import com.gss.armory.persistence.DocumentDAO;
import com.gss.armory.persistence.WorkFlowDAO;
import com.gss.armory.util.DocAccessUtility;
import com.gss.common.service.MailService;
import com.gss.common.util.ApplicationConstants;
import com.gss.common.util.ApplicationMaps;
import com.gss.common.util.ApplicationUtilities;
import com.gss.security.domain.DocumentSearchDetails;
import com.gss.security.domain.RoleDetailsDTO;
import com.gss.security.domain.SuperficialRolesMapping;
import com.gss.security.domain.UserDetailsDTO;
import com.gss.security.domain.UserRoleMappingDTO;
import com.gss.security.persistence.AuthenticationDAO;


@Service
public class ProcessDocumentService {
	
	private static Logger logger = Logger.getLogger(ProcessDocumentService.class);
	
	@Autowired
	CommonDAO comDao;
	
	@Autowired
	WorkFlowDAO workflowDao;

	@Autowired
	DocumentDAO documentDAO;
	
	@Autowired
	MailService mailService;
	
	@Autowired
	AuthenticationDAO authenticationDAO;

	
	public void uploadAndSaveNewDoc(DocDetailsForm docDetailsForm){
		logger.debug("inside method(uploadAndSaveNewDoc): for document with docId: " + docDetailsForm.getDocId());
			DocGeneralDetailsDTO docGeneralDetailsDTO = ApplicationUtilities.getDocumentGenDTOfromDocUploadForm(docDetailsForm);
			String[] linkDocId = docDetailsForm.getLinkedDocId();
			Set<String> linkedDocIdset = new HashSet<String>();
			if(linkDocId!=null&&linkDocId.length>0)
				linkedDocIdset.addAll(Arrays.asList(linkDocId));
			docGeneralDetailsDTO.setDocumentStatus(DocumentFlowStatus.Wfip);
			try {
				comDao.saveDocumentDetails(docGeneralDetailsDTO);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
			if(docGeneralDetailsDTO.getDocId() > 0){
				if(secureAndSaveUploadedDoc(docDetailsForm.getDocContent(),docGeneralDetailsDTO.getDocId())){
					ApplicationMaps.DOCUMENT_ID_NAME_MAP.put(docGeneralDetailsDTO.getDocId(), docGeneralDetailsDTO.getDocName());
					DocumentWorkflowDetailsDTO documentWorkflowDetailsDTO = ApplicationUtilities.getDocumentWorkflowDetDTOfromDocUploadForm(docDetailsForm ,docGeneralDetailsDTO);
					List<DocumentLinkDTO> documentLinkDTOs = ApplicationUtilities.getDocumentLinkDtoObject(linkedDocIdset,docGeneralDetailsDTO.getDocId());
					try {
						documentDAO.saveDocumentLinking(documentLinkDTOs);
					} catch (Exception e1) {
						logger.error(e1.getMessage(),e1);
					}
					try {
						
						comDao.saveDocumentDetails(documentWorkflowDetailsDTO);
					} catch (Exception e) {
						logger.error(e.getMessage(),e);
					}
/*					for(DocMetaDataAttrForm attrForm:docDetailsForm.getMetaDataAttrList()){
						DocumentMetadataValueDTO metadataValueDTO = new DocumentMetadataValueDTO();
						metadataValueDTO.setDmaId(attrForm.getMetaDataAttrId());
						metadataValueDTO.setDmaValue(attrForm.getMetaDataAttrValue());
						metadataValueDTO.setDocId(docGeneralDetailsDTO.getDocId());
						ApplicationUtilities.populateCommonDetails(metadataValueDTO, true);
						metadataValueList.add(metadataValueDTO);
					}
					try {
						comDao.saveMetaDataValues(metadataValueList);
					} catch (Exception e) {
						//e.printStackTrace();
						logger.error(e.getMessage());
					}*/	
				}
			}
	}
	public void updateDocumentDetails(DocDetailsForm docDetailsForm)
	{
		logger.debug("inside method(updateAndSaveDocument): for document with docId: " + docDetailsForm.getDocId());
		DocGeneralDetailsDTO docGeneralDetailsDTO = ApplicationUtilities.getDocumentGenDTOfromDocUploadForm(docDetailsForm);
		docGeneralDetailsDTO.setDocId(docDetailsForm.getDocId());
//		docGeneralDetailsDTO.setDocumentStatus(DocumentFlowStatus.Wfip);
		String[] linkedDocId  = docDetailsForm.getLinkedDocId();
		String[] oldLinkedDocId = docDetailsForm.getOldLinkedDocument();
		List<DocumentMetadataValueDTO> metadataValueList = new ArrayList<DocumentMetadataValueDTO>();
		Map<String, List<DocumentLinkDTO>> map = ApplicationUtilities.documentLinkingUpdation(linkedDocId,oldLinkedDocId,docDetailsForm.getDocId());
		List<DocumentLinkDTO> documentLinksToadd = map.get("add");
		List<DocumentLinkDTO> documentLinksToDelete= map.get("delete");
		try {
			comDao.updateDocDetails(docGeneralDetailsDTO);
		} catch (Exception e1) {
			logger.error(e1.getMessage(),e1);
		}
		DocAttDTO attDTO = null;
		try {
			attDTO = workflowDao.loadDocAtrrdetail(docDetailsForm.getDocId());
		} catch (Exception e3) {
			logger.error(e3.getMessage(),e3);
		}
		if(documentLinksToDelete.size()!=0 || documentLinksToDelete!=null)
			try {
				documentDAO.deleteDocumentLinking(documentLinksToDelete);
			} catch (Exception e2) {
				logger.error(e2.getMessage(),e2);
			}
		if(documentLinksToadd.size()!=0 || documentLinksToadd!=null)
			try {
				documentDAO.saveDocumentLinking(documentLinksToadd);
			} catch (Exception e2) {
				logger.error(e2.getMessage(),e2);
			}
/*		for(DocMetaDataAttrForm attrForm:docDetailsForm.getMetaDataAttrList()){
			DocumentMetadataValueDTO metadataValueDTO = new DocumentMetadataValueDTO();
			metadataValueDTO.setDmaValueId(attrForm.getDmaValueId());
			metadataValueDTO.setDmaId(attrForm.getMetaDataAttrId());
			metadataValueDTO.setDmaValue(attrForm.getMetaDataAttrValue());
			metadataValueDTO.setDocId(docGeneralDetailsDTO.getDocId());
			ApplicationUtilities.populateCommonDetails(metadataValueDTO, true);
			metadataValueList.add(metadataValueDTO);
		}
		if(docDetailsForm.getDocTypeId()!=docDetailsForm.getOriginalDocTypeId()){
			String hql = "delete from DocumentMetadataValueDTO as obj where obj.docId = :docIdToDelete";
			Query deleteQuery = null;
			try {
				deleteQuery = comDao.getQuery(hql);
			} catch (Exception e) {
				//e.printStackTrace();
				logger.error(e.getMessage());
			}
			deleteQuery.setParameter("docIdToDelete", docDetailsForm.getDocId());
			int numberOfRowsdeleted = 0;
			try {
				numberOfRowsdeleted = comDao.updateDocumentDetails(deleteQuery);
			} catch (Exception e) {
				//e.printStackTrace();
				logger.error(e.getMessage());
			}
			if(numberOfRowsdeleted>0)
			{
				for(DocumentMetadataValueDTO metadataValueDTO:metadataValueList){
					if(metadataValueDTO.getDmaValueId()!=0)
						metadataValueList.remove(metadataValueDTO);
				}
			}
		}
		try {
			comDao.saveMetaDataValues(metadataValueList);
		} catch (Exception e1) {
			//e1.printStackTrace();
			logger.error(e1.getMessage());
		}*/
		if(docDetailsForm.getDocContent().getOriginalFilename()!=""){
			byte[] encryptedDoc;
			try {
				encryptedDoc = DocAccessUtility.encryptDocBytes(docDetailsForm.getDocContent().getBytes(), ApplicationConstants.OPEN_PWD, ApplicationConstants.EDIT_PWD);
				if(encryptedDoc!=null){
					attDTO.setAttach(encryptedDoc);
					attDTO.setAtt_orig_filename(docDetailsForm.getDocContent().getOriginalFilename());
					ApplicationUtilities.populateCommonDetails(attDTO, false);
					workflowDao.updateDocRow(attDTO);
				}
			} catch (IOException e) {
				logger.error(e.getMessage(),e);
			}
		}	
	}
	
	public void uploadAndSaveRenewDocument(RequestContext context,DocRenewalDetailsForm renewalDetailsForm) {
		logger.debug("inside method(uploadAndSaveRenewDocument): for document with docId: " + renewalDetailsForm.getDocId());
		
		DocGeneralDetailsDTO docGeneralDetailsDTO = ApplicationUtilities.getDocumentGenDTOfromDocRenewForm(renewalDetailsForm);
		docGeneralDetailsDTO.setDocumentStatus(DocumentFlowStatus.RenewWfip);
		docGeneralDetailsDTO.setDocCode(""+renewalDetailsForm.getDocIdToRenew());
		
		DocumentWorkflowDetailsDTO workflowDetailsDTO = new DocumentWorkflowDetailsDTO();		
  		long wfId = context.getFlowScope().getLong("currentWfId");
  		workflowDetailsDTO.setWfId(wfId);
		//DocumentCustodianDetailsDTO custodianDetailsDTO = ApplicationUtilities.getVaultDetalsFromDetailsForm(detailsForm);
		try {
			workflowDao.loadWorkflowDetails(workflowDetailsDTO);
			ApplicationUtilities.populateCommonDetails(workflowDetailsDTO, false);
			workflowDao.updateWfEventStatus(workflowDetailsDTO);
		} catch (Exception e1) {
			logger.error(e1.getMessage(),e1);
		}
		/*workflowDetailsDTO.setWfEventStatus(WorkflowEventStatus.CLOSED);
		
		DocGeneralDetailsDTO detailsDTO = new DocGeneralDetailsDTO();
		detailsDTO.setDocId(renewalDetailsForm.getDocId());
		try {
			workflowDao.loadDocGeneralDetals(detailsDTO);
		} catch (Exception e1) {
			//e1.printStackTrace();
			logger.error(e1.getMessage());
		}
		detailsDTO.setDocumentStatus(DocumentFlowStatus.Deactive);*/
		boolean resultOfRenewDocSave = false;
		try {
//			comDao.updateDocDetails(detailsDTO);
			comDao.saveDocumentDetails(docGeneralDetailsDTO);
			resultOfRenewDocSave = true;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		if(secureAndSaveUploadedDoc(renewalDetailsForm.getDocContent(),docGeneralDetailsDTO.getDocId())){
			DocumentWorkflowDetailsDTO documentWorkflowDetailsDTO = ApplicationUtilities.getDocumentWorkflowDetDTOfromRenewDocForm(renewalDetailsForm ,docGeneralDetailsDTO);
			try {
				comDao.saveDocumentDetails(documentWorkflowDetailsDTO);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
		}
		
		/*long docId = Long.parseLong(context.getFlowScope().get("docId").toString());
		logger.debug("renewing for document with docId: " + docId);1
		
		boolean statusOfOldDocUpdated = false;
		if(resultOfRenewDocSave){
			DocGeneralDetailsDTO docGeneralDetailsDTO2 = comDao.loadDocumentForId(docId);
			docGeneralDetailsDTO2.setDocumentStatus(DocumentFlowStatus.Renewed);
			try {
				comDao.updateDocDetails(docGeneralDetailsDTO2);
				statusOfOldDocUpdated = true;
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
		
		if(statusOfOldDocUpdated) {
			DocumentLinkDTO documentLinkDTO = new DocumentLinkDTO();
			documentLinkDTO.setParentDocId(docId);
			documentLinkDTO.setLinkedDocId(linkedDocId)
		}*/
	}
	public void changeDocumentVersionOld(DocRenewalDetailsForm renewalDetailsForm,RequestContext requestContext) throws IOException{
		logger.debug("inside method(changeDocumentVersion): for document with docId: " + renewalDetailsForm.getDocId());
		byte[] encryptedDoc;	
		DocAttDTO attDTO = null;
		try {
			attDTO = workflowDao.loadDocAtrrdetail(renewalDetailsForm.getDocId());
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		encryptedDoc = DocAccessUtility.encryptDocBytes(renewalDetailsForm.getDocContent().getBytes(), ApplicationConstants.OPEN_PWD, ApplicationConstants.EDIT_PWD);
		attDTO.setAttach(encryptedDoc);
		ApplicationUtilities.populateCommonDetails(attDTO, false);
		if(workflowDao.updateDocRow(attDTO)){
			DocGeneralDetailsDTO docGeneralDetailsDTO = ApplicationUtilities.getDocumentGenDTOfromDocRenewForm(renewalDetailsForm);
			docGeneralDetailsDTO.setVersion(attDTO.getVersion());
			docGeneralDetailsDTO.setDocId(renewalDetailsForm.getDocId());
			docGeneralDetailsDTO.setDocCode(ApplicationUtilities.generateDocumentCode(docGeneralDetailsDTO));
			updateDocCode(docGeneralDetailsDTO);
			requestContext.getFlowScope().put("statusMsg", "Version of document changed successfully");
		}
	}
	
	public DocRenewalDetailsForm changeDocumentVersion(DocRenewalDetailsForm renewalDetailsForm,RequestContext requestContext) throws IOException{
		logger.debug("inside method(changeDocumentVersion): for document with docId:" + renewalDetailsForm.getDocId());
		
		//get document details
		DocGeneralDetailsDTO generalDetailsDTO = ApplicationUtilities.getDocumentGenDTOfromDocRenewForm(renewalDetailsForm);
		generalDetailsDTO.setVersion(renewalDetailsForm.getVersion()+1);
		try {
			//create new document
			generalDetailsDTO.setDocId(0);
			generalDetailsDTO.setDocumentStatus(DocumentFlowStatus.Active);
			comDao.saveDocumentDetails(generalDetailsDTO);
			long newVersionDocId = generalDetailsDTO.getDocId();
			
			//update links
			copyDocumentLinksFromExpiredToRenewedDoc(renewalDetailsForm.getDocId(), newVersionDocId, true,DocLinkType.VersionChange);
			// copy user permission
			copyUserActivityDetails(renewalDetailsForm.getDocId(), newVersionDocId, true);
			//copy vault details
			copyVaultDetails(renewalDetailsForm.getDocId(), newVersionDocId, false);
			//copy authorised signatory
			copyAuthorisedSignatory(renewalDetailsForm.getDocId(), newVersionDocId, false);
			secureAndSaveUploadedDoc(renewalDetailsForm.getDocContent(), newVersionDocId);
			
			generalDetailsDTO.setDocCode(ApplicationUtilities.generateDocumentCode(generalDetailsDTO));
			updateDocCode(generalDetailsDTO);
			
			updateDocStatus(renewalDetailsForm.getDocId(), DocumentFlowStatus.Versioned);
			requestContext.getFlowScope().put("statusMsg", "Version of document changed successfully. New Document with code " + 
					generalDetailsDTO.getDocCode() + " has been added to the system.");
			
			
		} catch (Exception e1) {
			logger.error(e1.getMessage(), e1);
			requestContext.getFlowScope().put("statusMsg", "Version of document was not changed. Pls try again.");
		}
		
		renewalDetailsForm.setDocContent(null);
		return renewalDetailsForm;
		
	}
	
	public void updateDocCode(DocGeneralDetailsDTO documentDTO){
		String queryToUpdateDocCode = "Update DocGeneralDetailsDTO docDto set docDto.docCode = :docCode where docDto.docId = :docId";
		Query updateQuery = null;
		try {
			updateQuery = comDao.getQuery(queryToUpdateDocCode);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		updateQuery.setString("docCode", documentDTO.getDocCode());
		updateQuery.setLong("docId", documentDTO.getDocId());
		try {
			comDao.updateDocumentDetails(updateQuery);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
	}
	
	public boolean updateDocStatus(long docId, DocumentFlowStatus updatedStatus){
		String queryToUpdateDocCode = "Update DocGeneralDetailsDTO docDto set docDto.documentStatus = :documentStatus where docDto.docId = :docId";
		Query updateQuery = null;
		try {
			updateQuery = comDao.getQuery(queryToUpdateDocCode);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		updateQuery.setString("documentStatus", updatedStatus.toString());
		updateQuery.setLong("docId", docId);
		try {
			comDao.updateDocumentDetails(updateQuery);
			logger.debug("Doc Status for document with docId " + docId + " had been updated successfully.");
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return false;
	}
	
	public DocDetailsForm showDocumentDetail(RequestContext context){
		DocDetailsForm docDetailsForm = new DocDetailsForm();
		try 
		{
			long docId = context.getRequestParameters().getLong("docId");
			logger.debug("inside method(showDocumentDetail): for document with docId: " + docId);
			long wfId = context.getRequestParameters().getLong("wfId");
			String wfAction = context.getRequestParameters().get("workFlowAction");
			List<DocumentLinkDTO> documentLinkDTOs = comDao.loadLinkedDocument(docId);
			Map<Long, String> map = new HashMap<Long, String>();
			Map<Long, String> olderVersions = new HashMap<Long, String>();
			List<Long> list = new ArrayList<Long>();
			if(documentLinkDTOs.size()>0||documentLinkDTOs!=null){
				for(DocumentLinkDTO dto:documentLinkDTOs)
					{
						if(!dto.getLinkType().equals(DocLinkType.General))
							continue;
						map.put(dto.getParentDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getParentDocId()));
						list.add(dto.getLinkedDocId());
					}
			}
			List<DocumentLinkDTO> documentLinkDTOs2 = comDao.loadLinkDocumentbyParent(docId);
			if(documentLinkDTOs2.size()>0||documentLinkDTOs2!=null){
				for(DocumentLinkDTO dto:documentLinkDTOs2)
				{
					if(dto.getLinkType().equals(DocLinkType.General)){
						map.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getLinkedDocId()));
						list.add(dto.getLinkedDocId());
					}else if(dto.getLinkType().equals(DocLinkType.VersionChange)){
						olderVersions.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_NAME_MAP.get(dto.getLinkedDocId()));
					}
				}
			}
/*			List<DocumentMetadataValueDTO> attributesDTOs = docDetailsForm.getMetadataValueList();
			List<DocMetaDataAttrForm> attrFormList = new ArrayList<DocMetaDataAttrForm>();
			for(int i=0;i<attributesDTOs.size();i++)
				attrFormList.add(new DocMetaDataAttrForm());
			docDetailsForm.setMetaDataAttrList(attrFormList);*/
			DocGeneralDetailsDTO docGeneralDetailsDTO = new DocGeneralDetailsDTO();			
			docGeneralDetailsDTO.setDocId(docId);
			workflowDao.loadDocumentDetails(docGeneralDetailsDTO);
//			List<DocumentMetadataValueDTO> metadataValueList = documentDAO.loadMetaDataValue(docId);
//			docGeneralDetailsDTO.setMetadataValueList(metadataValueList);			
			docDetailsForm = ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(docGeneralDetailsDTO,null);
			List<DocumentAuthSignatoryDTO> authSignatoryList = workflowDao.getDocumentAuthSignatory(docId);
			context.getFlowScope().put("authSignList", authSignatoryList);
			context.getFlowScope().put("linkedDocumentMap", map);
			context.getFlowScope().put("linkedDocumentList", list);
			context.getFlowScope().put("currentWfId", wfId);
			context.getFlowScope().put("wfAction", wfAction);
			context.getFlowScope().put("docId", docId);
			context.getFlowScope().put("versionLinksMap", olderVersions);
			context.getFlowScope().put("docCatList", ApplicationMaps.DOC_TYP_DOC_CAT_MAP.get(docGeneralDetailsDTO.getDocTypeId()));
			context.getFlowScope().put("docSubCatList", ApplicationMaps.DOC_CAT_DOC_SUBCAT_MAP.get(docGeneralDetailsDTO.getDocCategoryId()));
			context.getFlowScope().put("currentDocStatus", docGeneralDetailsDTO.getDocumentStatus().toString());
		} 
		catch(DataAccessException accessException)
		{
			logger.error(accessException.getMessage(),accessException);
		}
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return docDetailsForm;
	}
	
	public DocRenewalDetailsForm getDocumentDetailsForDeactivation(RequestContext context){

		boolean activityStatus = false;
		DocRenewalDetailsForm docDetailsForm = new DocRenewalDetailsForm();
		try 
		{
			long docId = context.getRequestParameters().getLong("docId");
			logger.debug("inside method(getDocumentDetailsForDeactivation): for document with docId: " + docId);
			List<DocumentLinkDTO> documentLinkDTOs = comDao.loadLinkedDocument(docId);
			Map<Long, String> map = new HashMap<Long, String>();
			Map<Long, String> olderVersions = new HashMap<Long, String>();
			List<Long> list = new ArrayList<Long>();
			if(documentLinkDTOs.size()>0||documentLinkDTOs!=null){
				for(DocumentLinkDTO dto:documentLinkDTOs)
					{
						if(!dto.getLinkType().equals(DocLinkType.General))
							continue;
						map.put(dto.getParentDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getParentDocId()));
						list.add(dto.getLinkedDocId());
					}
			}
			List<DocumentLinkDTO> documentLinkDTOs2 = comDao.loadLinkDocumentbyParent(docId);
			if(documentLinkDTOs2.size()>0||documentLinkDTOs2!=null){
				for(DocumentLinkDTO dto:documentLinkDTOs2)
				{
					if(dto.getLinkType().equals(DocLinkType.General)){
						map.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getLinkedDocId()));
						list.add(dto.getLinkedDocId());
					}else if(dto.getLinkType().equals(DocLinkType.VersionChange)){
						olderVersions.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_NAME_MAP.get(dto.getLinkedDocId()));
					}
				}
			}

			DocGeneralDetailsDTO docGeneralDetailsDTO = new DocGeneralDetailsDTO();			
			docGeneralDetailsDTO.setDocId(docId);
			workflowDao.loadDocumentDetails(docGeneralDetailsDTO);
			docDetailsForm = ApplicationUtilities.getdocrenewalDetailsFromGeneralDetails(docGeneralDetailsDTO);
			docDetailsForm.setDocId(docId);
			List<DocumentAuthSignatoryDTO> authSignatoryList = workflowDao.getDocumentAuthSignatory(docId);
			
			List<DocActivityType> activityGroup = null;
			try {
				activityGroup = workflowDao.userActivityForDocument(docId,ApplicationUtilities.getCurrentUser());
			} catch (Exception e1) {
				logger.error(e1.getMessage(),e1);
			}
			if(null != activityGroup && activityGroup.size()!=0){
				activityStatus = true;
			}
			
			context.getFlowScope().put("authSignList", authSignatoryList);
			context.getFlowScope().put("linkedDocumentMap", map);
			context.getFlowScope().put("linkedDocumentList", list);
			context.getFlowScope().put("docId", docId);
			context.getFlowScope().put("docCatList", ApplicationMaps.DOC_TYP_DOC_CAT_MAP.get(docGeneralDetailsDTO.getDocTypeId()));
			context.getFlowScope().put("docSubCatList", ApplicationMaps.DOC_CAT_DOC_SUBCAT_MAP.get(docGeneralDetailsDTO.getDocCategoryId()));
			context.getFlowScope().put("activityStatus", activityStatus);
			context.getFlowScope().put("versionLinksMap", olderVersions);
		} 
		catch(DataAccessException accessException)
		{
			logger.error(accessException.getMessage(),accessException);
		}
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return docDetailsForm;
	
	
	}
	
	public DocRenewalDetailsForm getExpiredDocumentDetails(RequestContext context)
	{
		DocRenewalDetailsForm docDetailsForm = new DocRenewalDetailsForm();
		try 
		{
			long docId = context.getRequestParameters().getLong("docId");
			logger.debug("inside method(getExpiredDocumentDetails): for document with docId: " + docId);
			long wfId = context.getRequestParameters().getLong("wfId");
			String wfAction = context.getRequestParameters().get("workFlowAction");
			List<DocumentLinkDTO> documentLinkDTOs = comDao.loadLinkedDocument(docId);
			Map<Long, String> map = new HashMap<Long, String>();
			List<Long> list = new ArrayList<Long>();
			if(documentLinkDTOs.size()>0||documentLinkDTOs!=null){
			for(DocumentLinkDTO dto:documentLinkDTOs)
				{
					map.put(dto.getParentDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getParentDocId()));
					list.add(dto.getLinkedDocId());
				}
			}
			List<DocumentLinkDTO> documentLinkDTOs2 = comDao.loadLinkDocumentbyParent(docId);
			if(documentLinkDTOs2.size()>0||documentLinkDTOs2!=null){
				for(DocumentLinkDTO dto:documentLinkDTOs2)
				{
					map.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_CODE_MAP.get(dto.getLinkedDocId()));
					list.add(dto.getLinkedDocId());
				}
			}
/*			List<DocumentMetadataValueDTO> attributesDTOs = docDetailsForm.getMetadataValueList();
			List<DocMetaDataAttrForm> attrFormList = new ArrayList<DocMetaDataAttrForm>();
			for(int i=0;i<attributesDTOs.size();i++)
				attrFormList.add(new DocMetaDataAttrForm());
			docDetailsForm.setMetaDataAttrList(attrFormList);*/
			DocGeneralDetailsDTO docGeneralDetailsDTO = new DocGeneralDetailsDTO();			
			docGeneralDetailsDTO.setDocId(docId);
			workflowDao.loadDocumentDetails(docGeneralDetailsDTO);
			List<DocumentMetadataValueDTO> metadataValueList = documentDAO.loadMetaDataValue(docId);
			docGeneralDetailsDTO.setMetadataValueList(metadataValueList);			
			docDetailsForm = ApplicationUtilities.getdocrenewalDetailsFromGeneralDetails(docGeneralDetailsDTO);
			docDetailsForm.setDocIdToRenew(docId);
			docDetailsForm.setDocId(0);
			List<DocumentAuthSignatoryDTO> authSignatoryList = workflowDao.getDocumentAuthSignatory(docId);
			context.getFlowScope().put("authSignList", authSignatoryList);
			context.getFlowScope().put("linkedDocumentMap", map);
			context.getFlowScope().put("linkedDocumentList", list);
			context.getFlowScope().put("currentWfId", wfId);
			context.getFlowScope().put("wfAction", wfAction);
			context.getFlowScope().put("docId", docId);
			context.getFlowScope().put("docIdToRenew", docId);
			context.getFlowScope().put("docCatList", ApplicationMaps.DOC_TYP_DOC_CAT_MAP.get(docGeneralDetailsDTO.getDocTypeId()));
			context.getFlowScope().put("docSubCatList", ApplicationMaps.DOC_CAT_DOC_SUBCAT_MAP.get(docGeneralDetailsDTO.getDocCategoryId()));

		} 
		catch(DataAccessException accessException)
		{
			logger.error(accessException.getMessage(),accessException);
		}
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return docDetailsForm;
	
	}
/*	public DocRenewalDetailsForm getExpiredDocumentDetails(RequestContext requestContext)
	{	
		boolean activityStatus = false;
		DocRenewalDetailsForm renewalDetailsForm = new DocRenewalDetailsForm();
		DocGeneralDetailsDTO detailsDTO = new DocGeneralDetailsDTO();
		long docId = requestContext.getRequestParameters().getLong("docId");
		detailsDTO.setDocId(docId);
		List<DocumentLinkDTO> documentLinkDTOs = null;
		try {
			documentLinkDTOs = comDao.loadLinkedDocument(docId);
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e.getMessage());
		}
		Map<Long, String> map = new HashMap<Long, String>();
		List<Long> list = new ArrayList<Long>();
		String userName = ApplicationUtilities.getCurrentUser();
		List<DocActivityType> activityGroup = null;
		try {
			activityGroup = workflowDao.userActivityForDocument(docId,userName);
		} catch (Exception e1) {
			//e1.printStackTrace();
			logger.error(e1.getMessage());
		}
		DocActivityType activity=null;
		logger.debug(activityGroup.size());
		if(activityGroup.size()!=0){
			logger.debug("inside if");
			activity = activityGroup.get(0);
		}
		if(activity!=null){
			if(activity.equals(DocActivityType.Print)||activity.equals(DocActivityType.View)){
				activityStatus = true;
			}			
		}
		if(documentLinkDTOs.size()>0||documentLinkDTOs!=null){
		for(DocumentLinkDTO dto:documentLinkDTOs)
			{
				map.put(dto.getParentDocId(), ApplicationMaps.DOCUMENT_ID_NAME_MAP.get(dto.getParentDocId()));
				list.add(dto.getLinkedDocId());
			}
		}
		List<DocumentLinkDTO> documentLinkDTOs2 = null;
		try {
			documentLinkDTOs2 = comDao.loadLinkDocumentbyParent(docId);
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e.getMessage());
		}
		if(documentLinkDTOs2.size()>0||documentLinkDTOs2!=null){
			for(DocumentLinkDTO dto:documentLinkDTOs2)
			{
				map.put(dto.getLinkedDocId(), ApplicationMaps.DOCUMENT_ID_NAME_MAP.get(dto.getLinkedDocId()));
				list.add(dto.getLinkedDocId());
			}
		}
		DocumentCustodianDetailsDTO custodianDetailsDTO = null;
		try {
			custodianDetailsDTO = documentDAO.loadCustodianDetailforDocId(docId);
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e.getMessage());
		}
		requestContext.getFlowScope().put("vaultDetails", custodianDetailsDTO);
		requestContext.getFlowScope().put("linkedDocumentMap", map);
		requestContext.getFlowScope().put("linkedDocumentList", list);
		requestContext.getFlowScope().put("activityStatus", activityStatus);
		try {
			workflowDao.loadDocumentDetails(detailsDTO);
		} catch (Exception e1) {
			//e1.printStackTrace();
			logger.error(e1.getMessage());
		}
		List<DocumentMetadataValueDTO> metadataValueList = null;
		try {
			metadataValueList = documentDAO.loadMetaDataValue(docId);
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e.getMessage());
		}
		detailsDTO.setMetadataValueList(metadataValueList);
		renewalDetailsForm = ApplicationUtilities.getdocrenewalDetailsFromGeneralDetails(detailsDTO);
		return renewalDetailsForm;
	}
	public List<DocumentMetaDataAttributesDTO> loadAttrForDocType(DocDetailsForm docDetailsForm,String docTypeId,RequestContext requestContext){
		List<DocumentMetaDataAttributesDTO> attributesDTOs =documentMetaDataService.getDataAttributesDTOs(Integer.parseInt(docTypeId));
		logger.debug("number of attr available for docTypeId: " + docTypeId + " is: " + attributesDTOs.size());
		int originalTypeId = Integer.parseInt(requestContext.getRequestParameters().get("originalTypeId"));

		if(null == docDetailsForm)
			docDetailsForm = new DocDetailsForm();
		List<DocMetaDataAttrForm> attrFormList = new ArrayList<DocMetaDataAttrForm>();
		List<DocumentMetadataValueDTO> metadataValueList = docDetailsForm.getMetadataValueList();
		logger.debug(metadataValueList.size());
		if(metadataValueList.size()==0||Integer.parseInt(docTypeId)!=originalTypeId){
			logger.debug(originalTypeId);
			if(originalTypeId!=0){
			for(int i=0;i<attributesDTOs.size();i++)
				attrFormList.add(new DocMetaDataAttrForm());
			}
			else{
				attrFormList=getAttrFormList(metadataValueList);
			}
		}
		else{
				attrFormList=getAttrFormList(metadataValueList);
			}
		docDetailsForm.setMetaDataAttrList(attrFormList);
		requestContext.getFlowScope().put("docDetailsForm",docDetailsForm);
		return attributesDTOs;
	}*/

	public boolean secureAndSaveUploadedDoc(MultipartFile docContent,Long docId){
			boolean isSuccess = false;
			logger.debug("inside method(secureAndSaveUploadedDoc: for document with docId: " + docId);
		try {
			//for saving in db open and edit password are hard coded for time being
			byte[] encryptedDoc;
			byte[] showwaterMark;
			DocAttDTO docAttDTO = new DocAttDTO();
			
			encryptedDoc = DocAccessUtility.encryptDocBytes(docContent.getBytes(), ApplicationConstants.OPEN_PWD, ApplicationConstants.EDIT_PWD);
			if(encryptedDoc!=null)
			{
				isSuccess = true;
				docAttDTO.setAtt_content_type(docContent.getContentType());
				docAttDTO.setAtt_orig_filename(docContent.getOriginalFilename());
				//docAttDTO.setAttach(docContent.getBytes());
				docAttDTO.setAttach(encryptedDoc);
				docAttDTO.setDoc_id(docId);
				ApplicationUtilities.populateCommonDetails(docAttDTO, true);
				comDao.saveDocumentDetails(docAttDTO);
			}
			else
			{
				logger.debug("inside method(secureAndSaveUploadedDoc: encrypted doc is null");
				throw new Exception();
			}
		} 
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return isSuccess;
	}

	
	public List<DocumentWorkflowDetailsDTO> workFlowList(){
		logger.debug("inside method(workFlowList): listing all methods... ");
		List<DocumentWorkflowDetailsDTO> workflowList = null;
		try{
			workflowList=comDao.getWorkFlowDetails();
		} 
		catch(DataAccessException accessException){
			logger.error(accessException.getMessage(),accessException);
		}
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return workflowList;
	}

	
	public DocAttDTO getAttachment(long docId,long linkedDocId) {
		logger.debug("inside method(getAttachment): for document with docId: "+docId);
        boolean waterMark=true;
        String userName = ApplicationUtilities.getCurrentUser();
        String openpwd = DocAccessUtility.generatePassword(userName);
        String editpwd = DocAccessUtility.generatePassword(userName);
        
        DetachedCriteria findingStatusCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
        findingStatusCriteria.setProjection(Projections.property("documentStatus"));
        findingStatusCriteria.add(Restrictions.eq("docId", docId));
        List<Object> statusList = comDao.loadAllByCriteria(findingStatusCriteria);
        
        if(! statusList.get(0).toString().equals(DocumentFlowStatus.Wfip.toString()) && 
        		! statusList.get(0).toString().equals(DocumentFlowStatus.RenewWfip.toString())) 
        {
	        List<DocActivityType> activityTypes = null;
			try {
				activityTypes = workflowDao.userActivityForDocument(docId, userName);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
	        if(activityTypes.size() > 0){
		        if(activityTypes.get(0).equals(DocActivityType.Print))
		        	waterMark = false;
	        }else{
	        	return new DocAttDTO();
	        }
        }
        else{
        	waterMark = false;
        }
        
        
        DocAttDTO attDTO = new DocAttDTO();
        DocAttDTO attDTOToBeSent = new DocAttDTO();
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(DocAttDTO.class);
        detachedCriteria.add(Restrictions.eq("doc_id", linkedDocId));
        attDTO = documentDAO.getDocAtt(detachedCriteria);
        
        
        if(null != attDTO && null != attDTO.getAttach())
        {
            attDTOToBeSent.setAtt_content_type(attDTO.getAtt_content_type());
            attDTOToBeSent.setAtt_id(attDTO.getAtt_id());
            attDTOToBeSent.setAtt_orig_filename(attDTO.getAtt_orig_filename());
            attDTOToBeSent.setDoc_id(attDTO.getDoc_id());
            if(waterMark)
            {
                attDTOToBeSent.setAttachEncrypted(DocAccessUtility.addWaterMark(attDTO.getAttach(), openpwd, editpwd));
                logger.debug("Adding Watermark....");
            }
            else
            {
                attDTOToBeSent.setAttachEncrypted(DocAccessUtility.encryptDocBytes(attDTO.getAttach(), openpwd, editpwd));
                
            }   
            logger.debug("Password to open the document: " + openpwd);
            mailService.sendMail(ApplicationUtilities.getCurrentUserEmail(), "The password for document "+docId+" is "+openpwd);
            return attDTOToBeSent;
         }
        else
        {
            logger.debug("attdto is Null: "+attDTO==null);
            return null;
        }
    }
	
	public List<DocGeneralDetailsDTO> getExpiredDocumentsList()
	{
		List<DocGeneralDetailsDTO> docDetails = new ArrayList<DocGeneralDetailsDTO>();
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
		detachedCriteria.add(Restrictions.eq("documentStatus", DocumentFlowStatus.Expired));
		
//		//temp change done for demo - pls revert after demo
//		
//		detachedCriteria.add(Restrictions.lt("docValidityEndDate", new Date(System.currentTimeMillis())));
		
		try {
			docDetails = documentDAO.getDocumentDetails(detachedCriteria);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return docDetails;
	}
	
	public List<DocGeneralDetailsDTO> searchDocumentDataForDocumentLookup(DocumentSearchDetails searchDetails) {

    	logger.debug("inside method(getDocuments)");
    	String appliedCriteria="";
    	boolean isGroupCompany = false;
    	boolean isStandaloneCompany = false;
    	boolean containsRole = false;
    	boolean isAuthorisedSignatoryIdProvided = false;
    	List<Integer> companyIdList = new ArrayList<Integer>();
    	List<Long> docIdAuthorizedSignatoryList = new ArrayList<Long>();
    	List<DocGeneralDetailsDTO> searchedDocumentList = new ArrayList<DocGeneralDetailsDTO>();
//    	List<DocDetailsForm> documentListToSend = new ArrayList<DocDetailsForm>();
    
    	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    	
    	//find details of company of searching user
    	int userCompanyId = userDetailsDTO.getCdId().intValue();
    	CompanyDetailsDTO userCompanyDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(userCompanyId);
    	
    	//checking company is group or standalone or subsidiary
    	if(userCompanyDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY))
    		isGroupCompany = true;
    	if(userCompanyDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.STANDALONE_COMPANY))
    		isStandaloneCompany = true;

    	//checking user has one of the roles in (ROLE_CC, ROLE_CCC, ROLE_OWNER)
    	List<GrantedAuthority> grantedAuthorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
    	for (GrantedAuthority grantedAuthorityToUser : grantedAuthorities) {
			RoleDetailsDTO roleOfUser = (RoleDetailsDTO) grantedAuthorityToUser;
			if(roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) 
					|| roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER) 
					|| roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_OWNER))
				containsRole = true;
		}
    	
    	//finding subsidiary companies if company of user is a group company and getting a list of company ids (including group company id)
    	if(isGroupCompany) {
    		int childCompanyCounter = 0;
    		companyIdList.add(userCompanyDTO.getCdId());
    		List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>();
    		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CompanyDetailsDTO.class);
    		detachedCriteria.add(Restrictions.eq("parentId", userCompanyDTO.getCdId()));
    		childCompanyList = comDao.loadAllByCriteria(detachedCriteria);
    		for(CompanyDetailsDTO childCompanyDTO : childCompanyList){
    			companyIdList.add(childCompanyDTO.getCdId());
    			childCompanyCounter++;
    		}
    		logger.debug("Number of subsidiary companies for group company with company Id: " + 
    				userCompanyDTO.getCdId() + " is:" + childCompanyCounter);
    	}
    	
    	//checking authorized signatory id is provided or not
    	if (null != searchDetails.getAuthSignatoryId() && !"".equalsIgnoreCase(searchDetails.getAuthSignatoryId())) {
    		isAuthorisedSignatoryIdProvided = true;
    	}
    	
    	//finding docIds list if authorized signatory id is provided
    	if(isAuthorisedSignatoryIdProvided){
    		DetachedCriteria criteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
			criteria.setProjection(Projections.property(("docId")));
			criteria.add(Restrictions.eq("userId",searchDetails.getAuthSignatoryId()));
			docIdAuthorizedSignatoryList = documentDAO.loadDocIdsForAuthSignatoryId(criteria);
    	}
    	
    	
    	//main searching loop...
    	
    	//user has role ROLE_CC or ROLE_CCC or ROLE_OWNER
    	if(containsRole) {
			logger.debug("User contains one of the roles as ROLE_CC or ROLE_CCC or ROLE_OWNER");
			//if company is group company
			if(isGroupCompany) {
				logger.debug("Searching document for a group company with company id: " + userCompanyId);
				//for each child company including group company
				for(Integer companyId : companyIdList){
					//if authorised signatory id provided
	    			if(isAuthorisedSignatoryIdProvided){
	    				logger.debug("Group Company: Authorised Signatory id provided");
	    				//for each docId where authorized signatory is same as provided
	    				for(Long docId : docIdAuthorizedSignatoryList) {
	    					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
							searchDetails.setDocId(docId);
							//applying the criteria on the basis of filter
							appliedCriteria = populateCriteriaForGroupCompany(documentSearchCriteria, 
									searchDetails, ApplicationMaps.COMPANYID_COMPANY_MAP.get(companyId).getCdId());
							
							try {
								List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
								Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
									tempDocSet.add(docGeneralDetailsDTO);
								}
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
									searchedDocumentList.add(docGeneralDetailsDTO);	
								}
							}
							catch(Throwable e) {
								logger.error(e.getMessage(),e);
							}
	    				}
	    			}
	    			else{
	    				logger.debug("Group Company: Authorised Signatory id not provided");
	    				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
	    				//applying the criteria on the basis of filter
						appliedCriteria = populateCriteriaForGroupCompany(documentSearchCriteria, 
								searchDetails, ApplicationMaps.COMPANYID_COMPANY_MAP.get(companyId).getCdId());
						
						try {
							List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
							Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
								tempDocSet.add(docGeneralDetailsDTO);
							}
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
								searchedDocumentList.add(docGeneralDetailsDTO);	
							}
						}
						catch(Throwable e) {
							logger.error(e.getMessage(),e);
						}
	    			}
				}
    		}
			//if company is subsidiary company
	    	else{
	    		logger.debug("Searching document for a subsidiary company with company id: " + userCompanyId);
	    		//if authorised signatory id provided
				if(isAuthorisedSignatoryIdProvided){
					logger.debug("Subsidiary Company: Authorised Signatory id provided");
					//for each docId where authorized signatory is same as provided
					for(Long docId : docIdAuthorizedSignatoryList) {
						DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
						searchDetails.setDocId(docId);
						//applying the criteria on the basis of filter
						appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
						
						try {
							List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
							Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
								tempDocSet.add(docGeneralDetailsDTO);
							}
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
								searchedDocumentList.add(docGeneralDetailsDTO);	
							}
						}
						catch(Throwable e) {
							logger.error(e.getMessage(),e);
						}
					}
				}
				else{
					logger.debug("Subsidiary Company: Authorised Signatory id not provided");
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
	    	}
    	}
    	else {
			logger.debug("User does not contains one of the roles as ROLE_CC or ROLE_CCC or ROLE_OWNER");
			//if authorised signatory id provided
			if(isAuthorisedSignatoryIdProvided){
				logger.debug("Authorised Signatory id provided");
				//for each docId where authorized signatory is same as provided
				for(Long docId : docIdAuthorizedSignatoryList) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
			}
			else{
				logger.debug("Authorised Signatory id not provided");
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				//applying the criteria on the basis of filter
				appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
				
				try {
					List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
					Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
						tempDocSet.add(docGeneralDetailsDTO);
					}
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
						searchedDocumentList.add(docGeneralDetailsDTO);	
					}
				}
				catch(Throwable e) {
					logger.error(e.getMessage(),e);
				}
			}
			
		}
    	
    	//if company is standalone company
    	if(isStandaloneCompany){
    		logger.debug("Searching document for a standalone company with company id: " + userCompanyId);
    		//if authorised signatory id provided
			if(isAuthorisedSignatoryIdProvided){
				logger.debug("Standalone Company: Authorised Signatory id provided");
				//for each docId where authorized signatory is same as provided
				for(Long docId : docIdAuthorizedSignatoryList) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
			}
			else{
				logger.debug("Standalone Company: Authorised Signatory id not provided");
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				//applying the criteria on the basis of filter
				appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
				
				try {
					List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
					Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
						tempDocSet.add(docGeneralDetailsDTO);
					}
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
						searchedDocumentList.add(docGeneralDetailsDTO);	
					}
				}
				catch(Throwable e) {
					logger.error(e.getMessage(),e);
				}
			}
    	}
    	
    	
    	
    	/*for (DocGeneralDetailsDTO detailsDTO : searchedDocumentList) {
			DocDetailsForm detailsForm = new DocDetailsForm();
			detailsForm = ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(detailsDTO);
			documentListToSend.add(detailsForm);
		}*/

		logger.debug("applied criteria while searching for document" + appliedCriteria);
		
		return searchedDocumentList;
    
	}
	
	public Set<DocGeneralDetailsDTO> searchedDocumentdata(DocumentSearchDetails documentSearchDetails) {
      
		Set<DocGeneralDetailsDTO> docGeneralDetailsDTOs = new HashSet<DocGeneralDetailsDTO>();
		UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
		List<String> list = new ArrayList<String>();
		for(GrantedAuthority authority:authorities)
		{
			RoleDetailsDTO detailsDTO = (RoleDetailsDTO) authority;
			list.add(detailsDTO.getRoleId());
		}
		DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
        populateCriteria(docCriteria,documentSearchDetails);
        
		try {
			if(list.contains(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) || list.contains(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER)){
				CompanyDetailsDTO companyDetailsDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(userDetailsDTO.getCdId());
	        	List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>();
	        	
	        	if(companyDetailsDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY)){
	        		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CompanyDetailsDTO.class);
	        		detachedCriteria.add(Restrictions.eq("parentId", companyDetailsDTO.getCdId()));
	        		childCompanyList = comDao.loadAllByCriteria(detachedCriteria);
	        	}
	        	
	        	logger.debug("******* Number of subsidiary companies : " + childCompanyList.size() + "    ************");
	        	
		    	if(childCompanyList.size() > 0){
		    		List<DocGeneralDetailsDTO> tempList = new ArrayList<DocGeneralDetailsDTO>();
		    		for(int i=0 ; i < childCompanyList.size() ; i++){
		    			tempList = documentDAO.loadDocData(docCriteria);
		    			
		    		}
		    		for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempList) {
		    			docGeneralDetailsDTOs.add(docGeneralDetailsDTO);
					}
		    	}
		    	else{
		    		List<DocGeneralDetailsDTO> tempList = new ArrayList<DocGeneralDetailsDTO>();
		    		tempList = documentDAO.loadDocData(docCriteria);
		    		for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempList) {
						docGeneralDetailsDTOs.add(docGeneralDetailsDTO);
					}
		    	}
			}
			else{
				List<DocGeneralDetailsDTO> tempList = new ArrayList<DocGeneralDetailsDTO>();
	    		tempList = documentDAO.loadDocData(docCriteria);
	    		for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempList) {
					docGeneralDetailsDTOs.add(docGeneralDetailsDTO);
				}
	    	}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}    
        return docGeneralDetailsDTOs;
    }

	private String populateDocumentSearchCriteria(DetachedCriteria docCriteria, DocumentSearchDetails documentSearchDetails) {
		String appliedCriteria = "";
		
		//Doc id
		if(!(ApplicationConstants.ALL_LONG == documentSearchDetails.getDocId())) {
    		docCriteria.add(Restrictions.eq("docId", documentSearchDetails.getDocId()));
    		appliedCriteria = appliedCriteria + " Document Id is provided as " + documentSearchDetails.getDocId() + "\n";
    	}
		//doc code
    	if(!ApplicationUtilities.checkIfNullOrBlank(documentSearchDetails.getDocCode())) {
    		docCriteria.add(Restrictions.ilike("docCode", documentSearchDetails.getDocCode(), MatchMode.ANYWHERE));
    		appliedCriteria = appliedCriteria + " Document Code is provided as " + documentSearchDetails.getDocCode() + "\n";
    	}
    	//doc name
        if(null != documentSearchDetails.getDocumentName() && !"".equals(documentSearchDetails.getDocumentName())) {
            docCriteria.add(Restrictions.ilike("docName", documentSearchDetails.getDocumentName(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " Document Name is provided as " + documentSearchDetails.getDocumentName() + "\n";
        }
        //issuing authority
        if(null != documentSearchDetails.getDocIssuingAuthority() && !"".equals(documentSearchDetails.getDocIssuingAuthority())) {
            docCriteria.add(Restrictions.ilike("docIssuingAuthority", documentSearchDetails.getDocIssuingAuthority(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " Document Issuing Authority is provided as " + documentSearchDetails.getDocIssuingAuthority() + "\n";
        }
        //doc entered with
        if(null != documentSearchDetails.getDocEnteredWith() && !"".equals(documentSearchDetails.getDocEnteredWith())) {
            docCriteria.add(Restrictions.ilike("docEnteredWith", documentSearchDetails.getDocEnteredWith(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " Aggrement Entered With is provided as " + documentSearchDetails.getDocEnteredWith() + "\n";
        }
        //doc type
        if(null!=documentSearchDetails.getDocTypeId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocTypeId().intValue())) {
            docCriteria.add(Restrictions.eq("docTypeId", documentSearchDetails.getDocTypeId()));
            appliedCriteria = appliedCriteria + " Document Type is selected as " 
            		+ ApplicationMaps.DOCUMENT_TYPE_ID_NAME_MAP.get(documentSearchDetails.getDocTypeId()) + "\n";
        }
        //doc category
        if(null != documentSearchDetails.getDocCategoryId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocCategoryId().intValue())) {
            docCriteria.add( Restrictions.eq("docCategoryId", documentSearchDetails.getDocCategoryId()));
            appliedCriteria = appliedCriteria + " Document Category is selected as " 
            		+ ApplicationMaps.DOCUMENT_CAT_ID_MAP.get(documentSearchDetails.getDocCategoryId()) + "\n";
        }
        //doc sub category
        if(null != documentSearchDetails.getDocSubCategoryId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocSubCategoryId().intValue())) {
            docCriteria.add(Restrictions.eq("docSubCategoryId", documentSearchDetails.getDocSubCategoryId()));
            appliedCriteria = appliedCriteria + " Document subcategory is selected as " 
            		+ ApplicationMaps.DOCUMENT_SUB_CAT_ID_MAP.get(documentSearchDetails.getDocSubCategoryId()) + "\n";
        }
        //department
        if(null != documentSearchDetails.getDepartment() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getDepartment().longValue())) {
            docCriteria.add(Restrictions.eq("docDepttId", documentSearchDetails.getDepartment()));
            appliedCriteria = appliedCriteria + " Document Department is selected as " 
            		+ ApplicationMaps.DEPTID_DEPTSNAME_MAP.get(documentSearchDetails.getDepartment().longValue()) + "\n";
        }
        //doc owner id
        if(null != documentSearchDetails.getOwnerId() && !"".equalsIgnoreCase(documentSearchDetails.getOwnerId())) {
        	docCriteria.add(Restrictions.eq("docOwnerId", documentSearchDetails.getOwnerId()));
        	appliedCriteria = appliedCriteria + " Document Owner Id is provided as " + documentSearchDetails.getOwnerId() +  "\n";
        }
        //doc status
        if(!(ApplicationConstants.ALL_STRING.equalsIgnoreCase(documentSearchDetails.getDocumentStatus()))) {
			if(documentSearchDetails.getDocumentStatus().equals(DocumentFlowStatus.Active.toString())) {
				docCriteria.add(Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Active),
	        						Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Due),
	        						Restrictions.eq("documentStatus", DocumentFlowStatus.Overdue))));	
			}else
				docCriteria.add(Restrictions.eq("documentStatus", DocumentFlowStatus.valueOf(documentSearchDetails.getDocumentStatus())));
			
			appliedCriteria = appliedCriteria + " Document Status is selected as " + documentSearchDetails.getDocumentStatus() + " \n";
		} else {
			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Wfip));
			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.RenewWfip));
			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Versioned));
			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Deactive));
			
			appliedCriteria = appliedCriteria + " Document Status is selected as " + ApplicationConstants.ALL_STRING + " \n";
		}
        //business unit
        if(null != documentSearchDetails.getRequestingPage() 
        		&& ApplicationConstants.RESTRICTED.equalsIgnoreCase(documentSearchDetails.getRequestingPage())) {
        	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
    		List<String> list = new ArrayList<String>();
    		for(GrantedAuthority authority : authorities) {
    			RoleDetailsDTO detailsDTO = (RoleDetailsDTO) authority;
    			list.add(detailsDTO.getRoleId());
    		}
    		
    		if(null != documentSearchDetails.getLocation() && ApplicationConstants.ALL_LONG != documentSearchDetails.getLocation().longValue()) {
    			if(list.contains(ApplicationConstants.ROLE_CONTROLLER)) {
    				if(userDetailsDTO.getBuId().longValue() == documentSearchDetails.getLocation().longValue()){
    					docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    					appliedCriteria = appliedCriteria + "Business unit is provided as " + userDetailsDTO.getBuId() + " \n";
    				}
    				else {
    					docCriteria.add(Restrictions.eq("docLocId", 0l));
    					appliedCriteria = appliedCriteria + "Business unit is provided as " + 0l + " \n";
    				}
    					
    			}
    			else if(list.contains(ApplicationConstants.ROLE_CENTRAL_CONTROLLER)) {
    				docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
    				appliedCriteria = appliedCriteria + "Business unit is provided as " + documentSearchDetails.getLocation() + " \n";
    			}
    		}
    		else{
    			if(list.contains(ApplicationConstants.ROLE_CONTROLLER)) {
    				docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    				appliedCriteria = appliedCriteria + "Business unit is provided as " + userDetailsDTO.getBuId() + " \n";
    			}
    		}
    	}
        else if(null != documentSearchDetails.getLocation() 
        		&& !(ApplicationConstants.ALL_LONG == documentSearchDetails.getLocation().longValue())) {
            docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
            appliedCriteria = appliedCriteria + "Business unit is provided as " + documentSearchDetails.getLocation() + " \n";
        }
        
		return appliedCriteria;
	}
	
	
	
	private String populateCriteriaForGroupCompany(DetachedCriteria docCriteria, DocumentSearchDetails documentSearchDetails,int companyId){
		String appliedCriteria = "";
    	if(!(ApplicationConstants.ALL_LONG == documentSearchDetails.getDocId())) {
    		docCriteria.add(Restrictions.eq("docId", documentSearchDetails.getDocId()));
    		appliedCriteria = appliedCriteria + " DocId,";
    	}
    	if(null != documentSearchDetails.getDocCode() && !"".equals(documentSearchDetails.getDocCode())) {
    		docCriteria.add(Restrictions.ilike("docCode", documentSearchDetails.getDocCode(), MatchMode.ANYWHERE));
    		appliedCriteria = appliedCriteria + " DocCode,";
    	}
        if(null != documentSearchDetails.getDocumentName() && !"".equals(documentSearchDetails.getDocumentName())) {
            docCriteria.add(Restrictions.ilike("docName", documentSearchDetails.getDocumentName(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocumentName,";
        }
        if(null != documentSearchDetails.getDocIssuingAuthority() && !"".equals(documentSearchDetails.getDocIssuingAuthority())) {
            docCriteria.add(Restrictions.ilike("docIssuingAuthority", documentSearchDetails.getDocIssuingAuthority(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocIssuingAuthority,";
        }
        if(null != documentSearchDetails.getDocEnteredWith() && !"".equals(documentSearchDetails.getDocEnteredWith())) {
            docCriteria.add(Restrictions.ilike("docEnteredWith", documentSearchDetails.getDocEnteredWith(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocEnteredWith,";
        }
        if(null!=documentSearchDetails.getDocTypeId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocTypeId().intValue())) {
            docCriteria.add(Restrictions.eq("docTypeId", documentSearchDetails.getDocTypeId()));
            appliedCriteria = appliedCriteria + " DocTypeId,";
        }
        if(null != documentSearchDetails.getDocCategoryId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocCategoryId().intValue())) {
            docCriteria.add( Restrictions.eq("docCategoryId", documentSearchDetails.getDocCategoryId()));
            appliedCriteria = appliedCriteria + " DocCategoryId,";
        }
        if(null != documentSearchDetails.getDocSubCategoryId() 
        		&& !(ApplicationConstants.ALL_INT.intValue() == documentSearchDetails.getDocSubCategoryId().intValue())) {
            docCriteria.add(Restrictions.eq("docSubCategoryId", documentSearchDetails.getDocSubCategoryId()));
            appliedCriteria = appliedCriteria + " DocSubCategoryId,";
        }
        if(null != documentSearchDetails.getDepartment() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getDepartment().longValue())) {
            docCriteria.add(Restrictions.eq("docDepttId", documentSearchDetails.getDepartment()));
            appliedCriteria = appliedCriteria + " DocDepttId,";
        }
        if(null != documentSearchDetails.getOwnerId() && !"".equalsIgnoreCase(documentSearchDetails.getOwnerId())) {
        	docCriteria.add(Restrictions.eq("docOwnerId", documentSearchDetails.getOwnerId()));
        	appliedCriteria = appliedCriteria + " DocOwnerId,";
        }			//filter for document owner
        
        if(!ApplicationUtilities.checkIfNullOrBlank(documentSearchDetails.getDocumentStatus())) {  
        		if(!(ApplicationConstants.ALL_STRING.equalsIgnoreCase(documentSearchDetails.getDocumentStatus()))) {
        			if(documentSearchDetails.getDocumentStatus().equals(DocumentFlowStatus.Active.toString())) {
        				docCriteria.add(Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Active),
        	        						Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Due),
        	        						Restrictions.eq("documentStatus", DocumentFlowStatus.Overdue))));	
        			}else
        				docCriteria.add(Restrictions.eq("documentStatus", DocumentFlowStatus.valueOf(documentSearchDetails.getDocumentStatus())));
        		} else {
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Wfip));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.RenewWfip));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Versioned));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Deactive));
        		}
        		appliedCriteria = appliedCriteria + " DocStatus";
        } else {
        	docCriteria.add(Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Active),
        					Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Due),
        					Restrictions.eq("documentStatus", DocumentFlowStatus.Overdue))));
        }
        
        if(null != documentSearchDetails.getRequestingPage() 
        		&& ApplicationConstants.RESTRICTED.equalsIgnoreCase(documentSearchDetails.getRequestingPage())) {
        	
        	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
    		List<String> list = new ArrayList<String>();
    		for(GrantedAuthority authority:authorities)
    		{
    			RoleDetailsDTO detailsDTO = (RoleDetailsDTO) authority;
    			list.add(detailsDTO.getRoleId());
    		}
    		if(list.contains(ApplicationConstants.ROLE_CENTRAL_CONTROLLER)){
    			 if(null != documentSearchDetails.getLocation() 
    					 && !(ApplicationConstants.ALL_LONG == documentSearchDetails.getLocation().longValue())) {
    				 docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
    		     }
    		}
    		else if(list.contains(ApplicationConstants.ROLE_CONTROLLER)){
    			 if(null != documentSearchDetails.getLocation() 
    					&& !(ApplicationConstants.ALL_LONG == documentSearchDetails.getLocation().longValue())) {
    				 	if(userDetailsDTO.getBuId().equals(documentSearchDetails.getLocation())) {
    				 		docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    				 	}
    				 	else {
    				 		docCriteria.add(Restrictions.eq("docLocId", 0l));
    				 	}
    		        }else{
    		        	docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    		        }
    			
    	    }
    		appliedCriteria = appliedCriteria + " DocLocId";
    	}
        else if(null != documentSearchDetails.getLocation() 
        		&& !(ApplicationConstants.ALL_LONG == documentSearchDetails.getLocation().longValue())) {
            docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
            appliedCriteria = appliedCriteria + " DocLocId";
        }
        
        //added by Chandan on 04-08-2012 to filter documents on the basis of company
        docCriteria.add(Restrictions.eq("docCompanyId", companyId));
        
        return appliedCriteria;
	}
	
    private String populateCriteria(DetachedCriteria docCriteria, DocumentSearchDetails documentSearchDetails) {
      
    	String appliedCriteria = "";
    	if(!(ApplicationConstants.ALL_LONG == documentSearchDetails.getDocId())) {
    		docCriteria.add(Restrictions.eq("docId", documentSearchDetails.getDocId()));
    		appliedCriteria = appliedCriteria + " DocId,";
    	}
    	if(null != documentSearchDetails.getDocCode() && !"".equals(documentSearchDetails.getDocCode())) {
    		docCriteria.add(Restrictions.ilike("docCode", documentSearchDetails.getDocCode(), MatchMode.ANYWHERE));
    		appliedCriteria = appliedCriteria + " DocCode,";
    	}
        if(null != documentSearchDetails.getDocumentName() && !"".equals(documentSearchDetails.getDocumentName())) {
            docCriteria.add(Restrictions.ilike("docName", documentSearchDetails.getDocumentName(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocumentName,";
        }
        if(null != documentSearchDetails.getDocIssuingAuthority() && !"".equals(documentSearchDetails.getDocIssuingAuthority())) {
            docCriteria.add(Restrictions.ilike("docIssuingAuthority", documentSearchDetails.getDocIssuingAuthority(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocIssuingAuthority,";
        }
        if(null != documentSearchDetails.getDocEnteredWith() && !"".equals(documentSearchDetails.getDocEnteredWith())) {
            docCriteria.add(Restrictions.ilike("docEnteredWith", documentSearchDetails.getDocEnteredWith(), MatchMode.ANYWHERE));
            appliedCriteria = appliedCriteria + " DocEnteredWith,";
        }
        if(null!=documentSearchDetails.getDocTypeId() && !(ApplicationConstants.ALL_INT.equals(documentSearchDetails.getDocTypeId()))) {
            docCriteria.add(Restrictions.eq("docTypeId", documentSearchDetails.getDocTypeId()));
            appliedCriteria = appliedCriteria + " DocTypeId,";
        }
        if(null != documentSearchDetails.getDocCategoryId() && !(ApplicationConstants.ALL_INT.equals(documentSearchDetails.getDocCategoryId()))) {
            docCriteria.add( Restrictions.eq("docCategoryId", documentSearchDetails.getDocCategoryId()));
            appliedCriteria = appliedCriteria + " DocCategoryId,";
        }
        if(null != documentSearchDetails.getDocSubCategoryId() && !(ApplicationConstants.ALL_INT.equals(documentSearchDetails.getDocSubCategoryId()))) {
            docCriteria.add(Restrictions.eq("docSubCategoryId", documentSearchDetails.getDocSubCategoryId()));
            appliedCriteria = appliedCriteria + " DocSubCategoryId,";
        }
        if(null != documentSearchDetails.getDepartment() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getDepartment().longValue())) {
            docCriteria.add(Restrictions.eq("docDepttId", documentSearchDetails.getDepartment()));
            appliedCriteria = appliedCriteria + " DocDepttId,";
        }
        if(null != documentSearchDetails.getOwnerId() && !"".equalsIgnoreCase(documentSearchDetails.getOwnerId())) {
        	docCriteria.add(Restrictions.eq("docOwnerId", documentSearchDetails.getOwnerId()));
        	appliedCriteria = appliedCriteria + " DocOwnerId,";
        }			//filter for document owner
        
        if(!ApplicationUtilities.checkIfNullOrBlank(documentSearchDetails.getDocumentStatus())) {  
        		if(!(ApplicationConstants.ALL_STRING.equalsIgnoreCase(documentSearchDetails.getDocumentStatus()))) {
        			if(documentSearchDetails.getDocumentStatus().equals(DocumentFlowStatus.Active.toString())) {
        				docCriteria.add(Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Active),
        	        						Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Due),
        	        						Restrictions.eq("documentStatus", DocumentFlowStatus.Overdue))));	
        			}else
        				docCriteria.add(Restrictions.eq("documentStatus", DocumentFlowStatus.valueOf(documentSearchDetails.getDocumentStatus())));
        		} else {
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Wfip));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.RenewWfip));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Versioned));
        			docCriteria.add(Restrictions.ne("documentStatus", DocumentFlowStatus.Deactive));
        		}
        		appliedCriteria = appliedCriteria + " DocStatus as: " + documentSearchDetails.getDocumentStatus() + " - ";
        } else {
        	docCriteria.add(Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Active),
        					Restrictions.or(Restrictions.eq("documentStatus", DocumentFlowStatus.Due),
        					Restrictions.eq("documentStatus", DocumentFlowStatus.Overdue))));
        }
        
        if(null != documentSearchDetails.getRequestingPage() 
        		&& ApplicationConstants.RESTRICTED.equalsIgnoreCase(documentSearchDetails.getRequestingPage())) {
        	
        	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
    		List<String> list = new ArrayList<String>();
    		for(GrantedAuthority authority:authorities)
    		{
    			RoleDetailsDTO detailsDTO = (RoleDetailsDTO) authority;
    			list.add(detailsDTO.getRoleId());
    		}
    		if(list.contains(ApplicationConstants.ROLE_CENTRAL_CONTROLLER)){
    			 if(null != documentSearchDetails.getLocation() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getLocation())) {
    		            docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
    		        }
    		}
    		else if(list.contains(ApplicationConstants.ROLE_CONTROLLER)){
    			 if(null != documentSearchDetails.getLocation() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getLocation())) {
    				 	if(userDetailsDTO.getBuId().equals(documentSearchDetails.getLocation())){
    				 		docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    				 	}else{
    				 		docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
    				 	}
    		        }/*else{
    		        	docCriteria.add(Restrictions.eq("docLocId", userDetailsDTO.getBuId()));
    		        	
    		        }*/
    			
    	    }
    		appliedCriteria = appliedCriteria + " DocLocId";
    	}
        else if(null != documentSearchDetails.getLocation() && !(ApplicationConstants.ALL_LONG==documentSearchDetails.getLocation())) {
            docCriteria.add(Restrictions.eq("docLocId", documentSearchDetails.getLocation()));
            appliedCriteria = appliedCriteria + " DocLocId";
        }
        //added by Chandan on 04-08-2012 to filter documents on the basis of company
        docCriteria.add(Restrictions.eq("docCompanyId", ApplicationUtilities.getCurrentUserCompanyId()));
        
        return appliedCriteria;
    }
 
    public List<UserDetailsDTO> searchedUserData(UserSearchForm userSearchForm) {

    	logger.debug("inside method(searchedUserData)");
    	Set<UserDetailsDTO> searchedUserSet = new HashSet<UserDetailsDTO>();
    	List<UserDetailsDTO> finalSearchedUSerList = new ArrayList<UserDetailsDTO>();
    	DetachedCriteria criteria = DetachedCriteria.forClass(UserDetailsDTO.class);
        
        criteria.setProjection(Projections.distinct(Projections.projectionList().
        		add(Projections.property(("username")),"username").
        		add(Projections.property("userDisplayName"),"userDisplayName").
        		add(Projections.property("buId"),"buId").
        		add(Projections.property("deptId"),"deptId").
        		add(Projections.property("cdId"),"cdId").
        		add(Projections.property("emailId"),"emailId")));
        		
        UserDetailsDTO detailsAuthDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        
        criteria.setResultTransformer(Transformers.aliasToBean(UserDetailsDTO.class));
        String appliedCriteria = "";
        
        if(null != userSearchForm.getFormAction() && !ApplicationConstants.FORM_CHANGE_PERMISSION.equalsIgnoreCase(userSearchForm.getFormAction())) {
        	appliedCriteria = populateUserSearchCriteriaInViewUsers(criteria, userSearchForm, detailsAuthDTO);
        }
        else if(null != userSearchForm.getFormAction() && ApplicationConstants.FORM_CHANGE_PERMISSION.equalsIgnoreCase(userSearchForm.getFormAction())){
        	Set<UserDetailsDTO> tempUserList = populateUserSearchCriteriaInChangePermission(criteria, userSearchForm, detailsAuthDTO);
        	for (UserDetailsDTO userDetailsDTO : tempUserList) {
				finalSearchedUSerList.add(userDetailsDTO);
			}
        	appliedCriteria = populateUserSearchCriteria(criteria, userSearchForm, detailsAuthDTO);
        }
        else
        	appliedCriteria = populateUserSearchCriteria(criteria, userSearchForm, detailsAuthDTO);
        
        logger.debug("Applied criteria: " + appliedCriteria);
    	
        try{
	    	CompanyDetailsDTO companyDetailsDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(detailsAuthDTO.getCdId());
	    	List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>();
	    	if(null != companyDetailsDTO){
		    	if(!ApplicationConstants.ALL_INT.equals(detailsAuthDTO.getCdId())){
			    	if(companyDetailsDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY)){
			    		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CompanyDetailsDTO.class);
			    		detachedCriteria.add(Restrictions.eq("parentId", companyDetailsDTO.getCdId()));
			    		childCompanyList = comDao.loadAllByCriteria(detachedCriteria);
			    	}
		    	}
		    	else if(ApplicationConstants.ALL_INT.equals(detailsAuthDTO.getCdId())){
		    		childCompanyList = (List<CompanyDetailsDTO>) ApplicationMaps.COMPANYID_COMPANY_MAP.values();
		    	}
	    	}
	    	
	    	logger.debug("Number of subsidiary companies for company id: " + detailsAuthDTO.getCdId() + " are: " + childCompanyList.size());
	    	
	    	if(childCompanyList.size() > 0) {
	    		List<UserDetailsDTO> tempList = new ArrayList<UserDetailsDTO>();
	    		for(int i=0 ; i < childCompanyList.size() ; i++){
	    			tempList = (List<UserDetailsDTO>)authenticationDAO.loadAllBySearchCriteria(criteria);
	    			
	    		}
	    		for (UserDetailsDTO UserDetailsDTO : tempList) {
	    			searchedUserSet.add(UserDetailsDTO);
				}
	    		logger.debug(" Number of users loaded while there is a group company: " + searchedUserSet.size());
	    	}
	    	else {
	    		List<UserDetailsDTO> tempList = new ArrayList<UserDetailsDTO>();
	    		tempList = (List<UserDetailsDTO>)authenticationDAO.loadAllBySearchCriteria(criteria);
	    		for (UserDetailsDTO UserDetailsDTO : tempList) {
					searchedUserSet.add(UserDetailsDTO);
				}
	    		logger.debug(" Number of users loaded while there is a subsidiary company or standalone company: " + searchedUserSet.size());
	    	}
        }
        catch (Exception e) {
        	logger.error(e.getMessage(),e);
		}
    	    	
        for(UserDetailsDTO userFromUserSet : searchedUserSet){
        	finalSearchedUSerList.add(userFromUserSet);
        }
		return finalSearchedUSerList;
    }	
    private Set<UserDetailsDTO> populateUserSearchCriteriaInChangePermission(DetachedCriteria criteria,
    		UserSearchForm userSearchForm, UserDetailsDTO detailsAuthDTO){
    	String appliedCriteria = "";
    	
    	int companyId = detailsAuthDTO.getCdId();
    	CompanyDetailsDTO companyDetailsDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(companyId);
		logger.debug("company type: " + companyDetailsDTO.getCompanyType());
		
		List<UserDetailsDTO> userList = null;
		Set<UserDetailsDTO> superficialUserList = new HashSet<UserDetailsDTO>();
		
		if(ApplicationConstants.SUBSIDIARY_COMPANY.equalsIgnoreCase(companyDetailsDTO.getCompanyType())) {
			int parentCompanyId = companyDetailsDTO.getParentId();
			DetachedCriteria userCompanyCriteria = DetachedCriteria.forClass(UserDetailsDTO.class);
			userCompanyCriteria.add(Restrictions.eq("cdId", parentCompanyId));
			userList = authenticationDAO.loadAllBySearchCriteria(userCompanyCriteria);
		}
		if(null != userList){
			for (UserDetailsDTO user : userList) {
				Collection<GrantedAuthority> rolesList = user.getAuthorities();
				for (GrantedAuthority grantedAuthority : rolesList) {
					RoleDetailsDTO roleDetailsDTO = (RoleDetailsDTO) grantedAuthority;
					if(roleDetailsDTO.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_OWNER)
							|| roleDetailsDTO.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER)) {
						superficialUserList.add(user);
					}
				}				
			}
		}
    	return superficialUserList;
    }
    
    private String populateUserSearchCriteriaInViewUsers(DetachedCriteria criteria,
    		UserSearchForm userSearchForm, UserDetailsDTO detailsAuthDTO) {
    	String appliedCriteria = "";
    	
    	if(null != userSearchForm.getUserId() && !"".equals(userSearchForm.getUserId())){
            //criteria.add(Restrictions.ilike("this.username", userId, MatchMode.ANYWHERE));
        	criteria.add(Restrictions.eq("this.username", userSearchForm.getUserId()));
        	appliedCriteria += "userId, ";
        }
        if(null != userSearchForm.getUserName() && !"".equals(userSearchForm.getUserName())){
            criteria.add(Restrictions.ilike("this.userDisplayName", userSearchForm.getUserName(), MatchMode.ANYWHERE));
            appliedCriteria += "username, ";
        }
        if(null != userSearchForm.getBuId() && !(ApplicationConstants.ALL_LONG==userSearchForm.getBuId())){
            criteria.add(Restrictions.eq("this.buId", userSearchForm.getBuId()));
            appliedCriteria += "buisness unit, ";
        }
        if(null != userSearchForm.getDeptId() && !(ApplicationConstants.ALL_LONG==userSearchForm.getDeptId())){
            criteria.add(Restrictions.eq("this.deptId", userSearchForm.getDeptId()));
            appliedCriteria += "department, ";
        }
        if(null != userSearchForm.getCdId() && !ApplicationConstants.ALL_INT.equals(userSearchForm.getCdId())){
        	criteria.add(Restrictions.eq("this.cdId", userSearchForm.getCdId()));
        	appliedCriteria += "company";
        }
        
        return appliedCriteria;
    }
    
    private String populateUserSearchCriteria(DetachedCriteria criteria, UserSearchForm userSearchForm, UserDetailsDTO detailsAuthDTO) {
    	String appliedCriteria = "";
    	
    	if(null != userSearchForm.getUserId() && !"".equals(userSearchForm.getUserId())){
            //criteria.add(Restrictions.ilike("this.username", userId, MatchMode.ANYWHERE));
        	criteria.add(Restrictions.eq("this.username", userSearchForm.getUserId()));
        	appliedCriteria += "userId, ";
        }
        if(null != userSearchForm.getUserName() && !"".equals(userSearchForm.getUserName())){
            criteria.add(Restrictions.ilike("this.userDisplayName", userSearchForm.getUserName(), MatchMode.ANYWHERE));
            appliedCriteria += "username, ";
        }
        if(null != userSearchForm.getBuId() && !(ApplicationConstants.ALL_LONG==userSearchForm.getBuId())){
            criteria.add(Restrictions.eq("this.buId", userSearchForm.getBuId()));
            appliedCriteria += "buisness unit, ";
        }
        if(null != userSearchForm.getDeptId() && !(ApplicationConstants.ALL_LONG==userSearchForm.getDeptId())){
            criteria.add(Restrictions.eq("this.deptId", userSearchForm.getDeptId()));
            appliedCriteria += "department, ";
        }
        if(null != detailsAuthDTO.getCdId()){
        	if(ApplicationConstants.ALL_INT.equals(detailsAuthDTO.getCdId())){
        		appliedCriteria += "no restriction of company";
        	}
        	else if(!ApplicationConstants.ALL_INT.equals(detailsAuthDTO.getCdId())){
        		criteria.add(Restrictions.eq("this.cdId", detailsAuthDTO.getCdId()));
        		appliedCriteria += "company as user's company, ";
        	}
        }
        else{
        	criteria.add(Restrictions.eq("this.cdId",ApplicationUtilities.getCurrentUserCompanyId()));
        	appliedCriteria += "company as user's company, "; 
        }
        
        return appliedCriteria;
    }
    
    public List<String> searchUserForRole(String userId, String role){
    	DetachedCriteria detachedCriteria = DetachedCriteria.forClass(UserRoleMappingDTO.class);
    	ProjectionList projectionList = Projections.projectionList();
    	projectionList.add(Projections.property("userId"));
    	detachedCriteria.setProjection(projectionList);
    	//detachedCriteria.setProjection(Projections.projectionList().add(Projections.property("userId")));
    	logger.debug("inside method(searchUserForRole): provided userId: " + userId + ", provided roleId: " + role);
    	  if(null != userId && !"".equals(userId)){
              //criteria.add(Restrictions.ilike("this.username", userId, MatchMode.ANYWHERE));
          	detachedCriteria.add(Restrictions.eq("userId", userId));
          }
    	if(null != role && role.length() > 0){
    		detachedCriteria.add(Restrictions.eq("roleId", role));
    	}
    	List<String> userList = null;
		try {
			userList = documentDAO.loadUserForRoleWF(detachedCriteria);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
    	return userList;
    }
    
    public void updateDocumentLinking(RequestContext context){
    	String[] linkedDocId = context.getRequestParameters().getArray("linkedDocId");
    	String[] oldLinkedDocId = context.getRequestParameters().getArray("oldLinkedDocument");
    	long docId = context.getRequestParameters().getLong("docId");
		Map<String, List<DocumentLinkDTO>> map = ApplicationUtilities.documentLinkingUpdation(linkedDocId,oldLinkedDocId,docId);
		List<DocumentLinkDTO> documentLinksToadd = map.get("add");
		List<DocumentLinkDTO> documentLinksToDelete= map.get("delete");
		if(documentLinksToDelete.size()!=0 || documentLinksToDelete!=null)
			try {
				documentDAO.deleteDocumentLinking(documentLinksToDelete);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
		if(documentLinksToadd.size()!=0 || documentLinksToadd!=null)
			try {
				documentDAO.saveDocumentLinking(documentLinksToadd);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
    }
    
    public List<DocumentCategoryDTO> loadDocumentCatMap(DocDetailsForm detailsForm){
    	logger.debug("inside method(loadDocumentCatMap): for document with docId: " + detailsForm.getDocId());
    	List<DocumentCategoryDTO> docCatList= ApplicationMaps.DOC_TYP_DOC_CAT_MAP.get(detailsForm.getDocTypeId());
    	return docCatList;
    }
    
    /*public void getDocuments(DocumentSearchDetails searchDetails,RequestContext context) {
    	logger.debug("inside method(getDocuments)");
    	String appliedCriteria="";
    	List<DocGeneralDetailsDTO> docGeneralDetailsDTOs = new ArrayList<DocGeneralDetailsDTO>();
    	List<DocDetailsForm> detailsForms = new ArrayList<DocDetailsForm>();
    	
    	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<GrantedAuthority> authorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
		List<String> list = new ArrayList<String>();
		for(GrantedAuthority authority:authorities) {
			RoleDetailsDTO detailsDTO = (RoleDetailsDTO) authority;
			list.add(detailsDTO.getRoleId());
		}
    	
		if(list.contains(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) || list.contains(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER)
				|| list.contains(ApplicationConstants.ROLE_OWNER)) {
			CompanyDetailsDTO companyDetailsDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(userDetailsDTO.getCdId());
        	List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>();
        	
        	if(companyDetailsDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY)) {
        		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CompanyDetailsDTO.class);
        		detachedCriteria.add(Restrictions.eq("parentId", companyDetailsDTO.getCdId()));
        		childCompanyList = comDao.loadAllByCriteria(detachedCriteria);
        	}
        	
			logger.debug("******* Number of subsidiary companies : " + childCompanyList.size() + "    ************");

			if (childCompanyList.size() > 0) {
				for (int i = 0; i < childCompanyList.size(); i++) {
					if (null != searchDetails.getAuthSignatoryId() && !"".equalsIgnoreCase(searchDetails.getAuthSignatoryId())) {
						logger.debug("Searching document for a group company: authorised signatory id provided: id is: " +
										searchDetails.getAuthSignatoryId());
						DetachedCriteria criteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
						criteria.setProjection(Projections.property(("docId")));
						criteria.add(Restrictions.eq("userId",searchDetails.getAuthSignatoryId()));
						List<Long> docIdList = documentDAO.loadDocIdsForAuthSignatoryId(criteria);
						
						for (Long docId : docIdList) {
							DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
							searchDetails.setDocId(docId);
//							appliedCriteria = populateCriteria(docCriteria, searchDetails);
							appliedCriteria = populateCriteriaForGroupCompany(docCriteria, searchDetails,childCompanyList.get(i).getCdId());
							try {
								List<DocGeneralDetailsDTO> tempList = documentDAO.loadDocData(docCriteria);
								Set<DocGeneralDetailsDTO> tempSet = new HashSet<DocGeneralDetailsDTO>();
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempList) {
									tempSet.add(docGeneralDetailsDTO);
								}
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempSet) {
									docGeneralDetailsDTOs.add(docGeneralDetailsDTO);	
								}
//								docGeneralDetailsDTOs.addAll(documentDAO.loadDocData(docCriteria));
							} catch (Exception e) {
								logger.error(e.getMessage(), e);
							}
						}
					} else {
						DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
						logger.debug("searching Document for a group company: authorised signatory not provided.");
//						appliedCriteria = populateCriteria(docCriteria, searchDetails);
						appliedCriteria = populateCriteriaForGroupCompany(docCriteria, searchDetails,childCompanyList.get(i).getCdId());
						try {
							List<DocGeneralDetailsDTO> tempList = documentDAO.loadDocData(docCriteria);
							Set<DocGeneralDetailsDTO> tempSet = new HashSet<DocGeneralDetailsDTO>();
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempList) {
								tempSet.add(docGeneralDetailsDTO);
							}
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempSet) {
								docGeneralDetailsDTOs.add(docGeneralDetailsDTO);	
							}
							
						} catch (Exception e) {
							logger.error(e.getMessage(), e);
						}
					}
				}
			}
			else{
				if (null != searchDetails.getAuthSignatoryId() && !"".equalsIgnoreCase(searchDetails.getAuthSignatoryId())) {
					logger.debug("Searching document not for a group company: authorised signatory id provided: id is: " 
									+ searchDetails.getAuthSignatoryId());
					
					DetachedCriteria criteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
					criteria.setProjection(Projections.property(("docId")));
					criteria.add(Restrictions.eq("userId",searchDetails.getAuthSignatoryId()));
					List<Long> docIdList = documentDAO.loadDocIdsForAuthSignatoryId(criteria);

					for (Long docId : docIdList) {
						DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
						searchDetails.setDocId(docId);
						appliedCriteria = populateCriteria(docCriteria, searchDetails);
						try {
							docGeneralDetailsDTOs.addAll(documentDAO.loadDocData(docCriteria));
						} catch (Exception e) {
							logger.error(e.getMessage(), e);
						}
					}
				} else {
					DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					logger.debug("searching Document not for a group company: authorised signatory not provided.");
					appliedCriteria = populateCriteria(docCriteria, searchDetails);

					try {
						docGeneralDetailsDTOs = documentDAO.loadDocData(docCriteria);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
				logger.debug("Number of documents loaded: " + docGeneralDetailsDTOs.size());
			}
		}
		else {
		System.out.println("number of documents other than current user company: " + docGeneralDetailsDTOs.size());
			if (null != searchDetails.getAuthSignatoryId() && !"".equalsIgnoreCase(searchDetails.getAuthSignatoryId())) {
				logger.debug("Searching document not for a group company: authorised signatory id provided: id is: " 
								+ searchDetails.getAuthSignatoryId());
				
				DetachedCriteria criteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
				criteria.setProjection(Projections.property(("docId")));
				criteria.add(Restrictions.eq("userId",searchDetails.getAuthSignatoryId()));
				List<Long> docIdList = documentDAO.loadDocIdsForAuthSignatoryId(criteria);

				for (Long docId : docIdList) {
					DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					appliedCriteria = populateCriteria(docCriteria, searchDetails);
					try {
						docGeneralDetailsDTOs.addAll(documentDAO.loadDocData(docCriteria));
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			} else {
				DetachedCriteria docCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				logger.debug("searching Document not for a group company: authorised signatory not provided.");
				appliedCriteria = populateCriteria(docCriteria, searchDetails);

				try {
					docGeneralDetailsDTOs = documentDAO.loadDocData(docCriteria);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
				}
			}
			logger.debug("Number of documents loaded: " + docGeneralDetailsDTOs.size());
		}

		for (DocGeneralDetailsDTO detailsDTO : docGeneralDetailsDTOs) {
			DocDetailsForm detailsForm = new DocDetailsForm();
			detailsForm = ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(detailsDTO);
			detailsForms.add(detailsForm);
		}

		logger.debug("applied criteria while searching for document" + appliedCriteria);
		context.getFlowScope().put("documentList", detailsForms);
	}*/
    
    public void getDocuments(DocumentSearchDetails searchDetails,RequestContext context) {
    	logger.debug("inside method(getDocuments)");
    	
    	//method rewritten on 26/02/2013
    	
    	boolean havingRole = false;			//boolean for having role as central controller, chief central controller or owner (true - have role)
    	boolean authSignIdProvided = false;	//boolean for authorized signatory id provided in filters or not (true - provided)
    	boolean isGroupCompany = false;		//boolean for company of user is group company (true - group company)
    	boolean isSubsidiaryCompany = false;//boolean for company of user is subsidiary company (true - subsidiary company)
    	boolean isStandAloneComapny = false;//boolean for company of user is stand alone company (true - stand alone company)
    	boolean isCustodianId = false;		//boolean for custodian id is provided for searching (true - custodian id provided)
    	List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>(); // if user's company is group company then list of child companies
    	
    	//check for having role as central controller, chief central controller or owner
    	UserDetailsDTO currentUserDetails = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    	logger.debug("Current user active is: " + currentUserDetails.getUserDisplayName() + "(" + currentUserDetails.getUsername() + ")");
    	
    	List<GrantedAuthority> grantedAuthoritiesList = (List<GrantedAuthority>) currentUserDetails.getAuthorities();
    	List<RoleDetailsDTO> rolesList = new ArrayList<RoleDetailsDTO>();
    	for(GrantedAuthority authority : grantedAuthoritiesList) {
    		RoleDetailsDTO roleDetails = (RoleDetailsDTO)authority;
    		rolesList.add(roleDetails);
    	}
    	logger.debug("Number of roles for user with user id: " + currentUserDetails.getUsername() + " are: " + rolesList.size());
    	if(null != rolesList && rolesList.size() > ApplicationConstants.ALL_INT.intValue()) {
    		for(RoleDetailsDTO roleDetailsObject : rolesList) {
    			if(roleDetailsObject.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) 
    					|| roleDetailsObject.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER)
    					|| roleDetailsObject.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_OWNER)) {
    				havingRole = true;		//check for role is true
    			}
    		}
    	}
    	
    	//checking the company is group company, subsidiary company or standalone company.
    	CompanyDetailsDTO companyObject = ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId());
//    	System.out.println("companyObject = "+companyObject);
    	if(null!=companyObject){
    		if(companyObject.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY))
        		isGroupCompany = true;
        	else if(companyObject.getCompanyType().equalsIgnoreCase(ApplicationConstants.SUBSIDIARY_COMPANY))
        		isSubsidiaryCompany = true;
        	else if(companyObject.getCompanyType().equalsIgnoreCase(ApplicationConstants.STANDALONE_COMPANY))
        		isStandAloneComapny = true;
    	}    	
    	logger.debug("User's company is a " + (isGroupCompany ? "Group Company" : (isSubsidiaryCompany ? "Subsidiary Company" : "Standalone Company")));
    	
    	
    	//checking if custodian id is provided or not
    	if(!ApplicationUtilities.checkIfNullOrBlank(searchDetails.getCustodianId())) {
    		isCustodianId = true;
    	}
    	
    	//checking whether authorized signatory is provided or not
    	if(!ApplicationUtilities.checkIfNullOrBlank(searchDetails.getAuthSignatoryId())) {
    		authSignIdProvided = true;
    	}
    	
    	List<DocumentCustodianDetailsDTO> docIdsForCustodianName = new ArrayList<DocumentCustodianDetailsDTO>();
    	List<Long> docIdListIfAuthorisedSignatoryIsProvided = new ArrayList<Long>();
    	Set<Long> docIdSetForSearching = new HashSet<Long>();
    	
    	
    	if(isCustodianId && authSignIdProvided) {
    		DetachedCriteria custodianCriteria = DetachedCriteria.forClass(DocumentCustodianDetailsDTO.class);
    		custodianCriteria.setProjection(Projections.property("docId"));
    		custodianCriteria.add(Restrictions.ilike("custodianName", searchDetails.getCustodianId().trim().toLowerCase(),MatchMode.ANYWHERE));
    		docIdsForCustodianName = documentDAO.loadDocIdsForCustodianId(custodianCriteria);
    		
    		DetachedCriteria authSignDocIdCriteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
    		authSignDocIdCriteria.setProjection(Projections.property("docId"));
    		authSignDocIdCriteria.add(Restrictions.eq("userId", searchDetails.getAuthSignatoryId()));
    		docIdListIfAuthorisedSignatoryIsProvided = documentDAO.loadDocIdsForAuthSignatoryId(authSignDocIdCriteria);
    		
    		List<Long> tempList = new ArrayList<Long>();
    		for(Object custodianObject : docIdsForCustodianName) {
    			for(Object authSignObject : docIdListIfAuthorisedSignatoryIsProvided) {
    				if(Long.parseLong(authSignObject.toString()) == Long.parseLong(custodianObject.toString())) {
    					tempList.add(Long.parseLong(custodianObject.toString()));
    				}
    			}
    		}
    		
    		for(Long docIds : tempList) {
    			docIdSetForSearching.add(docIds);
    		}
    		logger.debug("Number of documents where custodian id is like " + searchDetails.getCustodianId() 
    				+ " and authorised signatory id as " + searchDetails.getAuthSignatoryId()
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ") 
    				+ docIdSetForSearching.size() 
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ")  
    				+ docIdSetForSearching);
    	}
    	//if custodian id is provided fetching the list of doc ids according to that custodian name
    	else if(isCustodianId) {
    		List<Long> tempList = new ArrayList<Long>();
    		DetachedCriteria custodianCriteria = DetachedCriteria.forClass(DocumentCustodianDetailsDTO.class);
    		custodianCriteria.setProjection(Projections.property("docId"));
    		custodianCriteria.add(Restrictions.ilike("custodianName", searchDetails.getCustodianId().trim().toLowerCase(),MatchMode.ANYWHERE));
    		tempList = documentDAO.loadDocIdsForCustodianId(custodianCriteria);
    		
    		for(Long docIds : tempList) {
    			docIdSetForSearching.add(docIds);
    		}
    		logger.debug("Number of documents where custodian id is like " + searchDetails.getCustodianId() 
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ")  
    				+ docIdSetForSearching.size() 
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ")  
    				+ docIdSetForSearching);
    	}
    	//if authorized signatory id is provided then document id list according to auth signatory id
    	else if(authSignIdProvided) {
    		List<Long> tempList = new ArrayList<Long>();
    		DetachedCriteria authSignDocIdCriteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
    		authSignDocIdCriteria.setProjection(Projections.property("docId"));
    		authSignDocIdCriteria.add(Restrictions.eq("userId", searchDetails.getAuthSignatoryId()));
    		tempList = documentDAO.loadDocIdsForAuthSignatoryId(authSignDocIdCriteria);
    		
    		for(Long docIds : tempList) {
    			docIdSetForSearching.add(docIds);
    		}
    		logger.debug("Number of documents where authorised signatory is " + searchDetails.getAuthSignatoryId() 
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ")  
    				+ docIdSetForSearching.size() + " which " 
    				+ (docIdSetForSearching.size() <= 1 ? " is " : " are ")  
    				+ docIdSetForSearching);
    	}
    	
    	
    	//if user's company is group company then list of child companies
    	if(isGroupCompany) {
    		logger.debug("Finding subsidiary companies for group company " 
    				+ ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()).getCdName() 
    				+ "(" + currentUserDetails.getCdId() + ")");
    		for(CompanyDetailsDTO company : ApplicationMaps.COMPANYID_COMPANY_MAP.values()) {
    			if(null != company.getParentId() 
    					&& ApplicationConstants.ALL_INT.intValue() != company.getParentId().intValue()) {
    				if(company.getParentId().intValue() == currentUserDetails.getCdId())
        				childCompanyList.add(company);	
    			}
    		}
    		logger.debug("subsidiary companies for group company '" 
    				+ ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()).getCdName()
    				+ "(" + currentUserDetails.getCdId() + ")' are: " + childCompanyList.size());
    	}
    	
    	
    	logger.debug("\nSpecifications according to filters while searching of documents: \n" 
    			+ "(1) Authorised signatory provided = " + (authSignIdProvided ? "Yes" : "No") + "\n"
    			+ "(2) User has one of the role as CC, CCC, Owner = " + (havingRole ? "Yes" : "No") + " \n"
    			+ "(3) Company of user is = " + (isGroupCompany ? "Group Company" : 
    				(isSubsidiaryCompany ? "Subsidiary Company" : "Standalone Company")));
    	
    	//criteria for document searching
    	List<DocGeneralDetailsDTO> searchedDocumentList = new ArrayList<DocGeneralDetailsDTO>();
    	String appliedCriteria = "\nApplied criteria while searching documents is: \n";
    	
    	//if group company
    	if(isGroupCompany) {
    		//is having role as central controller, chief central controller or owner
    		if(havingRole) {
    			
    			//if authorized signatory id provided
    			if(authSignIdProvided || isCustodianId) {
    				appliedCriteria += "authorized signatory id is provided as " + searchDetails.getAuthSignatoryId() + " \n";
    				for(Long docId : docIdSetForSearching) {
    					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
    					searchDetails.setDocId(docId);
    					appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
    					
    					//doc company id
    			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
    			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
    			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
    			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
    			        }
    					try {
    						searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
    					}
    					catch(Exception e) {
    						logger.error(e.getMessage(), e);
    					}
    				}
    			}
    			else {
    				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
    				appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
    				
					//doc company id
			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
			        }
			       
    				try {
    					searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
    				}
    				catch(Exception e) {
    					logger.error(e.getMessage(), e);
    				}
    			}
    		}
    		else {
    			//if authorized signatory id provided
    			if(authSignIdProvided || isCustodianId) {
    				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
    				appliedCriteria += "authorized signatory id is provided as " + searchDetails.getAuthSignatoryId() + " \n";
    				for(Long docId : docIdSetForSearching) {
    					searchDetails.setDocId(docId);
    					appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
    					
    					//doc company id
    			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
    			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
    			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
    			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
    			        }
    			        else {
    			        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
    			        	appliedCriteria = appliedCriteria + "Company is selected as " 
   			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
    			        }
    					
    					try {
    						searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
    					}
    					catch(Exception e) {
    						logger.error(e.getMessage(), e);
    					}
    				}
    			}
    			else {
    				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
    				appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
    				
					//doc company id
			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
			        }
			        else {
			        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
			        	appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
			        }
			       
    				try {
    					searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
    				}
    				catch(Exception e) {
    					logger.error(e.getMessage(), e);
    				}
    			}
    		}
    	}
    	
    	
    	//if subsidiary company
    	if(isSubsidiaryCompany) {
    		//if authorized signatory id provided
			if(authSignIdProvided || isCustodianId) {
				appliedCriteria += "authorized signatory id is provided as " + searchDetails.getAuthSignatoryId() + " \n";
				for(Long docId : docIdSetForSearching) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
					
					//doc company id
			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
			        }
			        else {
			        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
			        	appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
			        }
					
					try {
						searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
					}
					catch(Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
			else {
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
				
				//doc company id
		        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
		        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
		        	 appliedCriteria = appliedCriteria + "Company is selected as " 
		        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
		        }
		        else {
		        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
		        	appliedCriteria = appliedCriteria + "Company is selected as " 
		        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
		        }
		       
				try {
					searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
				}
				catch(Exception e) {
					logger.error(e.getMessage(), e);
				}
			}
    	}
    	
    	
    	//if stand alone company
    	if(isStandAloneComapny) {
    		//if authorized signatory id provided
			if(authSignIdProvided || isCustodianId) {
				appliedCriteria += "authorized signatory id is provided as " + searchDetails.getAuthSignatoryId() + " \n";
				for(Long docId : docIdSetForSearching) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
					
					//doc company id
			        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
			        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
			        	 appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
			        }
			        else {
			        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
			        	appliedCriteria = appliedCriteria + "Company is selected as " 
			        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
			        }
					
					try {
						searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
					}
					catch(Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
			}
			else {
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				appliedCriteria = populateDocumentSearchCriteria(documentSearchCriteria, searchDetails);
				
				//doc company id
		        if(ApplicationConstants.ALL_LONG != searchDetails.getCompanyId()) {
		        	 documentSearchCriteria.add(Restrictions.eq("docCompanyId", (int)searchDetails.getCompanyId()));   	
		        	 appliedCriteria = appliedCriteria + "Company is selected as " 
		        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(searchDetails.getCompanyId()) + " \n";
		        }
		        else {
		        	documentSearchCriteria.add(Restrictions.eq("docCompanyId", currentUserDetails.getCdId()));   	
		        	appliedCriteria = appliedCriteria + "Company is selected as " 
		        			 + ApplicationMaps.COMPANYID_COMPANY_MAP.get(currentUserDetails.getCdId()) + " \n";
		        }
		       
				try {
					searchedDocumentList.addAll(documentDAO.loadDocData(documentSearchCriteria));
				}
				catch(Exception e) {
					logger.error(e.getMessage(), e);
				}
			}
    	}
    	
    	logger.debug("Applied criteria was: \n" + appliedCriteria);
    	logger.debug("Number of docuemnts searched according to the selected criteria: " + searchedDocumentList.size());
    	
    	List<DocDetailsForm> documentListToSend = new ArrayList<DocDetailsForm>();
    	for (DocGeneralDetailsDTO detailsDTO : searchedDocumentList) {
    		DocDetailsForm detailsForm = new DocDetailsForm();
			detailsForm = ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(detailsDTO
					,documentDAO.getCustodianNameForDocId(detailsDTO.getDocId()));
			documentListToSend.add(detailsForm);
		}

		context.getFlowScope().put("documentList", documentListToSend);
		
    	/*String appliedCriteria="";
    	boolean isGroupCompany = false;
    	boolean isStandaloneCompany = false;
    	boolean containsRole = false;
    	boolean isAuthorisedSignatoryIdProvided = false;
    	List<Integer> companyIdList = new ArrayList<Integer>();
    	List<Long> docIdAuthorizedSignatoryList = new ArrayList<Long>();
    	List<DocGeneralDetailsDTO> searchedDocumentList = new ArrayList<DocGeneralDetailsDTO>();
    	List<DocDetailsForm> documentListToSend = new ArrayList<DocDetailsForm>();
    
    	UserDetailsDTO userDetailsDTO = (UserDetailsDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    	
    	//find details of company of searching user
    	int userCompanyId = userDetailsDTO.getCdId().intValue();
    	CompanyDetailsDTO userCompanyDTO = ApplicationMaps.COMPANYID_COMPANY_MAP.get(userCompanyId);
    	
    	//checking company is group or standalone or subsidiary
    	if(userCompanyDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.GROUP_COMPANY))
    		isGroupCompany = true;
    	if(userCompanyDTO.getCompanyType().equalsIgnoreCase(ApplicationConstants.STANDALONE_COMPANY))
    		isStandaloneCompany = true;

    	//checking user has one of the roles in (ROLE_CC, ROLE_CCC, ROLE_OWNER)
    	List<GrantedAuthority> grantedAuthorities = (List<GrantedAuthority>) userDetailsDTO.getAuthorities();
    	for (GrantedAuthority grantedAuthorityToUser : grantedAuthorities) {
			RoleDetailsDTO roleOfUser = (RoleDetailsDTO) grantedAuthorityToUser;
			if(roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) 
					|| roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER) 
					|| roleOfUser.getRoleId().equalsIgnoreCase(ApplicationConstants.ROLE_OWNER))
				containsRole = true;
		}
    	
    	//finding subsidiary companies if company of user is a group company and getting a list of company ids (including group company id)
    	if(isGroupCompany) {
    		int childCompanyCounter = 0;
    		companyIdList.add(userCompanyDTO.getCdId());
    		List<CompanyDetailsDTO> childCompanyList = new ArrayList<CompanyDetailsDTO>();
    		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(CompanyDetailsDTO.class);
    		detachedCriteria.add(Restrictions.eq("parentId", userCompanyDTO.getCdId()));
    		childCompanyList = comDao.loadAllByCriteria(detachedCriteria);
    		for(CompanyDetailsDTO childCompanyDTO : childCompanyList){
    			companyIdList.add(childCompanyDTO.getCdId());
    			childCompanyCounter++;
    		}
    		logger.debug("Number of subsidiary companies for group company with company Id: " + 
    				userCompanyDTO.getCdId() + " is:" + childCompanyCounter);
    	}
    	
    	//checking authorized signatory id is provided or not
    	if (null != searchDetails.getAuthSignatoryId() && !"".equalsIgnoreCase(searchDetails.getAuthSignatoryId())) {
    		isAuthorisedSignatoryIdProvided = true;
    	}
    	
    	//finding docIds list if authorized signatory id is provided
    	if(isAuthorisedSignatoryIdProvided){
    		DetachedCriteria criteria = DetachedCriteria.forClass(DocumentAuthSignatoryDTO.class);
			criteria.setProjection(Projections.property(("docId")));
			criteria.add(Restrictions.eq("userId",searchDetails.getAuthSignatoryId()));
			docIdAuthorizedSignatoryList = documentDAO.loadDocIdsForAuthSignatoryId(criteria);
    	}
    	
    	
    	//main searching loop...
    	
    	//user has role ROLE_CC or ROLE_CCC or ROLE_OWNER
    	if(containsRole) {
			logger.debug("User contains one of the roles as ROLE_CC or ROLE_CCC or ROLE_OWNER");
			//if company is group company
			if(isGroupCompany) {
				logger.debug("Searching document for a group company with company id: " + userCompanyId);
				//for each child company including group company
				for(Integer companyId : companyIdList){
					//if authorised signatory id provided
	    			if(isAuthorisedSignatoryIdProvided){
	    				logger.debug("Group Company: Authorised Signatory id provided");
	    				//for each docId where authorized signatory is same as provided
	    				for(Long docId : docIdAuthorizedSignatoryList) {
	    					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
							searchDetails.setDocId(docId);
							//applying the criteria on the basis of filter
							appliedCriteria = populateCriteriaForGroupCompany(documentSearchCriteria, 
									searchDetails, ApplicationMaps.COMPANYID_COMPANY_MAP.get(companyId).getCdId());
							
							try {
								List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
								Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
									tempDocSet.add(docGeneralDetailsDTO);
								}
								for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
									searchedDocumentList.add(docGeneralDetailsDTO);	
								}
							}
							catch(Throwable e) {
								logger.error(e.getMessage(),e);
							}
	    				}
	    			}
	    			else{
	    				logger.debug("Group Company: Authorised Signatory id not provided");
	    				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
	    				//applying the criteria on the basis of filter
						appliedCriteria = populateCriteriaForGroupCompany(documentSearchCriteria, 
								searchDetails, ApplicationMaps.COMPANYID_COMPANY_MAP.get(companyId).getCdId());
						
						try {
							List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
							Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
								tempDocSet.add(docGeneralDetailsDTO);
							}
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
								searchedDocumentList.add(docGeneralDetailsDTO);	
							}
						}
						catch(Throwable e) {
							logger.error(e.getMessage(),e);
						}
	    			}
				}
    		}
			//if company is subsidiary company
	    	else{
	    		logger.debug("Searching document for a subsidiary company with company id: " + userCompanyId);
	    		//if authorised signatory id provided
				if(isAuthorisedSignatoryIdProvided){
					logger.debug("Subsidiary Company: Authorised Signatory id provided");
					//for each docId where authorized signatory is same as provided
					for(Long docId : docIdAuthorizedSignatoryList) {
						DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
						searchDetails.setDocId(docId);
						//applying the criteria on the basis of filter
						appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
						
						try {
							List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
							Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
								tempDocSet.add(docGeneralDetailsDTO);
							}
							for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
								searchedDocumentList.add(docGeneralDetailsDTO);	
							}
						}
						catch(Throwable e) {
							logger.error(e.getMessage(),e);
						}
					}
				}
				else{
					logger.debug("Subsidiary Company: Authorised Signatory id not provided");
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
	    	}
    	}
    	else {
			logger.debug("User does not contains one of the roles as ROLE_CC or ROLE_CCC or ROLE_OWNER");
			//if authorised signatory id provided
			if(isAuthorisedSignatoryIdProvided){
				logger.debug("Authorised Signatory id provided");
				//for each docId where authorized signatory is same as provided
				for(Long docId : docIdAuthorizedSignatoryList) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
			}
			else{
				logger.debug("Authorised Signatory id not provided");
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				//applying the criteria on the basis of filter
				appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
				
				try {
					List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
					Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
						tempDocSet.add(docGeneralDetailsDTO);
					}
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
						searchedDocumentList.add(docGeneralDetailsDTO);	
					}
				}
				catch(Throwable e) {
					logger.error(e.getMessage(),e);
				}
			}
			
		}
    	
    	//if company is standalone company
    	if(isStandaloneCompany){
    		logger.debug("Searching document for a standalone company with company id: " + userCompanyId);
    		//if authorised signatory id provided
			if(isAuthorisedSignatoryIdProvided){
				logger.debug("Standalone Company: Authorised Signatory id provided");
				//for each docId where authorized signatory is same as provided
				for(Long docId : docIdAuthorizedSignatoryList) {
					DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
					searchDetails.setDocId(docId);
					//applying the criteria on the basis of filter
					appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
					
					try {
						List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
						Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
							tempDocSet.add(docGeneralDetailsDTO);
						}
						for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
							searchedDocumentList.add(docGeneralDetailsDTO);	
						}
					}
					catch(Throwable e) {
						logger.error(e.getMessage(),e);
					}
				}
			}
			else{
				logger.debug("Standalone Company: Authorised Signatory id not provided");
				DetachedCriteria documentSearchCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
				//applying the criteria on the basis of filter
				appliedCriteria = populateCriteria(documentSearchCriteria,searchDetails);
				
				try {
					List<DocGeneralDetailsDTO> tempDocList = documentDAO.loadDocData(documentSearchCriteria);
					Set<DocGeneralDetailsDTO> tempDocSet = new HashSet<DocGeneralDetailsDTO>();
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocList) {
						tempDocSet.add(docGeneralDetailsDTO);
					}
					for (DocGeneralDetailsDTO docGeneralDetailsDTO : tempDocSet) {
						searchedDocumentList.add(docGeneralDetailsDTO);	
					}
				}
				catch(Throwable e) {
					logger.error(e.getMessage(),e);
				}
			}
    	}
    	
    	
    	
    	for (DocGeneralDetailsDTO detailsDTO : searchedDocumentList) {
			DocDetailsForm detailsForm = new DocDetailsForm();
			detailsForm = ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(detailsDTO);
			documentListToSend.add(detailsForm);
		}

		logger.debug("applied criteria while searching for document" + appliedCriteria);
		
		context.getFlowScope().put("documentList", documentListToSend);*/
    }
    
    
    public void browseDocuments(RequestContext context) {
    	String idString = context.getRequestParameters().get("typeId");
    	 String[] temp;
    	 String delimiter = "_";
    	 temp = idString.split(delimiter);
    	 DocumentSearchDetails details = new DocumentSearchDetails();
    	 details.setDocumentStatus(DocumentFlowStatus.Active.toString());
    	 for(int i =0; i < temp.length ; i++){
    		 details.setDocTypeId(Integer.parseInt(temp[0]));
    		 if(temp.length==2)
    			 details.setDocCategoryId(Integer.parseInt(temp[1]));
    		 if(temp.length==3)
    			 details.setDocSubCategoryId(Integer.parseInt(temp[2]));
    	 }
    	/* List<DocDetailsForm> detailsForms = new ArrayList<DocDetailsForm>();
    	 DetachedCriteria criteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
    	  populateCriteria(criteria,details);
    	  List<DocGeneralDetailsDTO> docGeneralDetailsDTOs = null;
		try {
			docGeneralDetailsDTOs = (List<DocGeneralDetailsDTO>) documentDAO.loadDocData(criteria);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
          for(DocGeneralDetailsDTO detailsDTO:docGeneralDetailsDTOs){
          	DocDetailsForm detailsForm = new DocDetailsForm();
          	detailsForm=ApplicationUtilities.getDocumentDetailfromDocGeneralDetailDTO(detailsDTO);
          	detailsForms.add(detailsForm);
          }
          context.getFlowScope().put("documentList", detailsForms);*/
    	 
    	 getDocuments(details, context);
    }

	public void loadUserDetails(UserDetailsDTO detailsDTO) {
		try {
			comDao.loadUserDetails(detailsDTO);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
	}

    public DocRenewalDetailsForm deactivateDoc(RequestContext context) {
    	long docId = context.getRequestParameters().getLong("docId");
    	String currentStatus = context.getRequestParameters().get("currentStatus");
    	logger.debug("inside method(deactivateDoc): for document with docId: " + docId);
    	
    	List<DocumentLinkDTO> linkDTOs = new ArrayList<DocumentLinkDTO>();
    	DocLinkType newLinkType = DocLinkType.General;
    	
    	try {
	    	if(null != currentStatus && DocumentFlowStatus.Active.toString().equalsIgnoreCase(currentStatus)){
	    		if(updateDocStatus(docId, DocumentFlowStatus.Deactive)) {
	    			context.getFlowScope().put("statusMsg", "Document Deactivated Successfully");
	        		linkDTOs.addAll(comDao.loadLinkDocumentbyParent(docId,DocLinkType.General));
	        		linkDTOs.addAll(comDao.loadLinkedDocument(docId,DocLinkType.General));
	        		newLinkType = DocLinkType.Suspunded;
	        		
	        		sendDeactivationMail(docId);	// send mail notification for deactivation
	        		deleteActivityMapping(docId);	// delete all activity mappings and give print rights to users having role CC,CCC,OWNER
	        		addEntryOfWorkflowSuspended(docId);		// add entry of suspended in database
	    		}
	        	else
	        		context.getFlowScope().put("statusMsg", "Document Deactivation Failed. Please contact Administrator.");
	    		
	    		
	    	}else {
	    		if(updateDocStatus(docId, DocumentFlowStatus.Active)){
	        		context.getFlowScope().put("statusMsg", "Document Reactivated Successfully");
	        		linkDTOs.addAll(comDao.loadLinkDocumentbyParent(docId,DocLinkType.Suspunded));
	        		linkDTOs.addAll(comDao.loadLinkedDocument(docId,DocLinkType.Suspunded));
	        		newLinkType = DocLinkType.General;
	        		removeEntryOfWorkflowSuspended(docId);
	    		}
	        	else
	        		context.getFlowScope().put("statusMsg", "Document Reactivation Failed. Please contact Administrator.");
	    	}
	    	
	    	
	    	
	    	// update links to deactivated document
	    	if(linkDTOs.size() > 0){
	    		if(!linkDTOs.get(0).getLinkType().equals(newLinkType)){
		    		for(DocumentLinkDTO existingLink : linkDTOs){
		    			existingLink.setLinkType(newLinkType);
		    		}
		    		documentDAO.saveDocumentLinking(linkDTOs);
	    		}
	    	}
    	}catch (Exception e) {
    		logger.error(e.getMessage(),e);
		}
    	
    	return getDocumentDetailsForDeactivation(context);
    }
    
    public boolean sendDeactivationMail(long docId) {

    	List<String> usersList = new ArrayList<String>();
		
		DetachedCriteria docGeneralCriteria = DetachedCriteria.forClass(DocGeneralDetailsDTO.class);
		docGeneralCriteria.add(Restrictions.eq("docId", docId));
		List<DocGeneralDetailsDTO> documentGeneralList = comDao.loadAllByCriteria(docGeneralCriteria);
		DocGeneralDetailsDTO documentObject = documentGeneralList.get(0);
		
		String masterCode = documentObject.getDocTypeId() + "#" + documentObject.getDocLocId() + "#" + documentObject.getDocDepttId();
		DetachedCriteria docRevApprCriteria = DetachedCriteria.forClass(DocReviewerApproverForWFDTO.class);
		docRevApprCriteria.add(Restrictions.eq("masterCode", masterCode));
		List<DocReviewerApproverForWFDTO> reviewerApproverList = comDao.loadAllByCriteria(docRevApprCriteria);
		DocReviewerApproverForWFDTO reviewerApprover = reviewerApproverList.get(0);
		
		String reviewerId = reviewerApprover.getReviewer();		//reviewer User Id
		String approverId = reviewerApprover.getApprover();		//approver User Id
		String uploaderId = documentObject.getStrCreatedAuthor(); //uploader User Id
		
		usersList.add(reviewerId);
		usersList.add(approverId);
		usersList.add(uploaderId);
		
		DetachedCriteria superficialCriteria = DetachedCriteria.forClass(SuperficialRolesMapping.class);
		superficialCriteria.add(Restrictions.eq("ldId", documentObject.getDocLocId()));
		superficialCriteria.add(Restrictions.eq("cdId", documentObject.getDocCompanyId()));
		List<SuperficialRolesMapping> superficialUsersList = comDao.loadAllByCriteria(superficialCriteria);
		
		if(null != superficialUsersList){
			for (SuperficialRolesMapping superficialUser : superficialUsersList) {
				usersList.add(superficialUser.getUserId());
			}
		}
		
		Set<String> emailSet = new HashSet<String>();
		for(String userId : usersList){
			emailSet.add(ApplicationMaps.USERID_EMAIL_MAP.get(userId));
		}
		
		String []toEmailArray = emailSet.toArray(new String[0]);
		String emailSubject = "Regarding Document Deactivation.";
		String emailBody = getMessageForDeactivationMail(documentObject);
		
		boolean resultOfMailSending = mailService.sendMailNotification(toEmailArray, null, emailBody, emailSubject);
		
		logger.debug("Mail Sending Result: " + resultOfMailSending);
		
		return resultOfMailSending;
    }
    
    private String getMessageForDeactivationMail(DocGeneralDetailsDTO docDetailsDTO) {
		StringBuilder mailMessage = new StringBuilder();
		
		mailMessage.append("<br> Dear All, <br><br>");
		mailMessage.append("The document with the following details is deactivated. <br><br>");
		mailMessage.append("Document Details: <br><br>");
		mailMessage.append("<table border='1'>");
		mailMessage.append("<tr> <td> Name: &nbsp; </td> <td>" + docDetailsDTO.getDocName() + "</td></tr>");
		if(!ApplicationUtilities.checkIfNullOrBlank(docDetailsDTO.getDocCode())) {
			mailMessage.append("<tr> <td> Document Code: &nbsp; </td> <td>" + docDetailsDTO.getDocCode() + "</td></tr>");
		}
		
		mailMessage.append("<tr> <td> Type: &nbsp; </td> <td>" + docDetailsDTO.getDocType() + "</td></tr>");
		mailMessage.append("<tr> <td> Category: &nbsp; </td> <td>" + docDetailsDTO.getDocCategory() + "</td></tr>");
		mailMessage.append("<tr> <td> Sub Category: &nbsp; </td> <td>" + docDetailsDTO.getDocSubCategory() + "</td></tr>");
		mailMessage.append("<tr> <td> Location: &nbsp; </td> <td>" + docDetailsDTO.getDocLocation() + "</td></tr>");
		mailMessage.append("<tr> <td> Department: &nbsp; </td> <td>" + docDetailsDTO.getDocDepartment() + "</td></tr>");
		mailMessage.append("</table><br><br>");
		mailMessage.append("Thanks and Regards<br>DMS Administrator");
		
		return mailMessage.toString();
	}
    
	public boolean deleteActivityMapping(long docId) {
		DetachedCriteria activityCriteria = DetachedCriteria.forClass(UserActivityGroup.class);
		activityCriteria.add(Restrictions.eq("docId", docId));
		List<UserActivityGroup> oldActivityMappingList = comDao.loadAllByCriteria(activityCriteria);
		Set<String> finalUserSet = new HashSet<String>();
		if(null != oldActivityMappingList && 0 != oldActivityMappingList.size()){
			Set<String> usersSet = new HashSet<String>();
			for (UserActivityGroup userActivity : oldActivityMappingList) {
				usersSet.add(userActivity.getUsername());
			}
			
			List<UserDetailsDTO> userDtoList = new ArrayList<UserDetailsDTO>();
			for(String user : usersSet){
				DetachedCriteria detachedCriteria = DetachedCriteria.forClass(UserDetailsDTO.class);
				detachedCriteria.add(Restrictions.eq("username", user));
				userDtoList.addAll((List<UserDetailsDTO>) authenticationDAO.loadAllBySearchCriteria(detachedCriteria));
			}
			
			Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
			HashMap<String, Set<String>> USER_ID_ROLE_ID_MAP = new HashMap<String, Set<String>>();
			Set<String> roleIdSet;
			for(UserDetailsDTO userDetailsDTO : userDtoList){
				authorities = userDetailsDTO.getAuthorities();
				roleIdSet = new HashSet<String>();
				for (GrantedAuthority authority : authorities) {
					RoleDetailsDTO roleDetailsDTO = (RoleDetailsDTO) authority;
					roleIdSet.add(roleDetailsDTO.getRoleId());
				}
				USER_ID_ROLE_ID_MAP.put(userDetailsDTO.getUsername(), roleIdSet);
			}
			
			
			for(String userId : USER_ID_ROLE_ID_MAP.keySet()){
				Set<String> roleSet = USER_ID_ROLE_ID_MAP.get(userId);
				for(String roleId : roleSet){
					if(roleId.equalsIgnoreCase(ApplicationConstants.ROLE_CENTRAL_CONTROLLER) || 
							roleId.equalsIgnoreCase(ApplicationConstants.ROLE_CHIEF_CENTRAL_CONTROLLER) ||
							roleId.equalsIgnoreCase(ApplicationConstants.ROLE_OWNER)){
						finalUserSet.add(userId);
					}
				}
			}
			
			boolean resultOfDelete = comDao.removeOldMappingList(oldActivityMappingList);
			logger.debug("resultofdelete: " + resultOfDelete);
		}
		
		boolean resultOfSave = false;
		if(null != finalUserSet && 0 != finalUserSet.size()){
			logger.debug("Saving new default mapping for docId: " + docId);
			for(String defaultUser : finalUserSet){
				UserActivityGroup userActivityGroup = new UserActivityGroup();
				userActivityGroup.setActivityType(DocActivityType.Print);
				userActivityGroup.setdocId(docId);
				userActivityGroup.setUsername(defaultUser);
				resultOfSave = comDao.saveNewDefaultDeactivateMapping(userActivityGroup);
				logger.debug("resultOfSave of new default deactivate mapping: " + resultOfSave);
			}
		}
    	return resultOfSave;
    }
	
	public void addEntryOfWorkflowSuspended(long docId) {

		DetachedCriteria docWorkFlowCriteria = DetachedCriteria.forClass(DocumentWorkflowDetailsDTO.class);
		DocumentWorkflowDetailsDTO workFlowOpenEntry = null;
		docWorkFlowCriteria.add(Restrictions.eq("docId", docId));
		List<DocumentWorkflowDetailsDTO> docWorkflowList = comDao.loadAllByCriteria(docWorkFlowCriteria);
		
		for (DocumentWorkflowDetailsDTO documentWorkflowDetailsDTO : docWorkflowList) {
			if(documentWorkflowDetailsDTO.getWfEventStatus().equals(WorkflowEventStatus.OPEN))
				workFlowOpenEntry = documentWorkflowDetailsDTO;
		}
		if(null != workFlowOpenEntry){
			workFlowOpenEntry.setWfEventStatus(WorkflowEventStatus.SUSPENDED);
			try {
				comDao.updateWfRow(workFlowOpenEntry);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}
	
	public void removeEntryOfWorkflowSuspended(long docId) {
		
		DetachedCriteria docWorkFlowCriteria = DetachedCriteria.forClass(DocumentWorkflowDetailsDTO.class);
		DocumentWorkflowDetailsDTO workFlowSuspendedEntry = null;
		docWorkFlowCriteria.add(Restrictions.eq("docId", docId));
		List<DocumentWorkflowDetailsDTO> docWorkflowList = comDao.loadAllByCriteria(docWorkFlowCriteria);
		
		for (DocumentWorkflowDetailsDTO documentWorkflowDetailsDTO : docWorkflowList) {
			if(documentWorkflowDetailsDTO.getWfEventStatus().equals(WorkflowEventStatus.SUSPENDED))
				workFlowSuspendedEntry = documentWorkflowDetailsDTO;
		}
		if(null != workFlowSuspendedEntry){
			workFlowSuspendedEntry.setWfEventStatus(WorkflowEventStatus.OPEN);
			try {
				comDao.updateWfRow(workFlowSuspendedEntry);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

    public List<DocMetaDataAttrForm> getAttrFormList(List<DocumentMetadataValueDTO> metadataValueList) {
    	List<DocMetaDataAttrForm> attrFormList  = new ArrayList<DocMetaDataAttrForm>();
		for(DocumentMetadataValueDTO metadataValueDTO:metadataValueList){
			DocMetaDataAttrForm metaDataAttrForm = new DocMetaDataAttrForm();
			metaDataAttrForm.setDmaValueId(metadataValueDTO.getDmaValueId());
			metaDataAttrForm.setMetaDataAttrId(metadataValueDTO.getDmaId());
			metaDataAttrForm.setMetaDataAttrValue(metadataValueDTO.getDmaValue());
			attrFormList.add(metaDataAttrForm);
		}			
		return attrFormList;
    }
    
    public DocumentCustodianDetailsForm loadDocCustodianDetails(RequestContext requestContext) {
    	DocumentCustodianDetailsForm documentCustodianDetailsForm = new DocumentCustodianDetailsForm();
    	
    	long docId=requestContext.getRequestParameters().getLong("docId");
    	
    	DetachedCriteria detachedCriteria = DetachedCriteria.forClass(DocumentCustodianDetailsDTO.class);
    	detachedCriteria.add(Restrictions.eq("docId", docId));
    	try {
			DocumentCustodianDetailsDTO custodianDetailsDTO =  documentDAO.loadCustodianDetailforDocId(docId);
			if(null != custodianDetailsDTO){
				documentCustodianDetailsForm.setCustodianDepttId(custodianDetailsDTO.getCustodianDepttId());
				documentCustodianDetailsForm.setCustodianDesig(custodianDetailsDTO.getCustodianDesig());
				documentCustodianDetailsForm.setCustodianId(custodianDetailsDTO.getCustodianId());
				documentCustodianDetailsForm.setCustodianLocId(custodianDetailsDTO.getCustodianLocId());
				documentCustodianDetailsForm.setCustodianName(custodianDetailsDTO.getCustodianName());
				documentCustodianDetailsForm.setVaultId(custodianDetailsDTO.getCustodianDepttId());
				documentCustodianDetailsForm.setVaultLocation(custodianDetailsDTO.getVaultLocation());
				documentCustodianDetailsForm.setVaultNumber(custodianDetailsDTO.getVaultNumber());
				documentCustodianDetailsForm.setDocId(docId);
			}else{
				logger.debug("inside method(loadCustodianDetails): custodian details not found for docId: " + docId);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
    	
    	return documentCustodianDetailsForm;
    }
    
    public void copyVaultDetails(long docIdToBeRenewed, long newDocId,boolean deleteForSourceDoc) {
    	try{
    		DocumentCustodianDetailsDTO custodianDetailsDTO =  documentDAO.loadCustodianDetailforDocId(docIdToBeRenewed);
    		if(null != custodianDetailsDTO){
    			DocumentCustodianDetailsDTO detailsForNewDoc = new DocumentCustodianDetailsDTO();
    			BeanUtils.copyProperties(custodianDetailsDTO, detailsForNewDoc);
    			detailsForNewDoc.setVaultId(0);
    			detailsForNewDoc.setDocId(newDocId);
    			workflowDao.saveVaultDetails(detailsForNewDoc);
    		}
    	}catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
    }
    
	public void copyUserActivityDetails(long docIdToBeRenewed, long newDocId,boolean deleteForSourceDoc) {
		List<UserActivityGroup> activityGroups = null;
		List<UserActivityGroup> activityGroupForRenewedDoc = new ArrayList<UserActivityGroup>();
		UserActivityGroup newActivityGroup = null;
		try {
			activityGroups = documentDAO.getUserDocumentActivity(docIdToBeRenewed);
			for(UserActivityGroup activityGroup:activityGroups)
			{
				newActivityGroup = new UserActivityGroup();
				newActivityGroup.setdocId(newDocId);
				newActivityGroup.setActivityType(activityGroup.getActivityType());
				newActivityGroup.setUsername(activityGroup.getUsername());
				activityGroupForRenewedDoc.add(newActivityGroup);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		if(activityGroupForRenewedDoc.size() > 0){
			try {
				documentDAO.saveUserActivity(activityGroupForRenewedDoc);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				logger.error(e.getMessage(),e);
			}
		}
		if(deleteForSourceDoc && null != activityGroups && activityGroups.size() > 0){
			try {
				documentDAO.deleteUserActivity(activityGroups);
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
			}
		}
	}
	
	public void copyDocumentLinksFromExpiredToRenewedDoc(long docIdToBeRenewed, long newDocId,
			boolean deleteLinksForSource,DocLinkType newLinkType) {
		try{
			logger.debug("inside method(copyDocumentLinksFromExpiredToRenewedDoc): copying links from " + docIdToBeRenewed + " to " + newDocId);
			// docs which have been linked to doc being renewed - link them to new doc
			List<DocumentLinkDTO> linksForRenewedDoc = new ArrayList<DocumentLinkDTO>();
			DocumentLinkDTO newLink = null;
			
			newLink = new DocumentLinkDTO();
			newLink.setParentDocId(newDocId);
			newLink.setLinkedDocId(docIdToBeRenewed);
			newLink.setLinkType(newLinkType);
			ApplicationUtilities.populateCommonDetails(newLink, true);
			linksForRenewedDoc.add(newLink);
			
			List<DocumentLinkDTO> linksAsParentId = comDao.loadLinkDocumentbyParent(docIdToBeRenewed);
			if(null != linksAsParentId && linksAsParentId.size() > 0){
				for(DocumentLinkDTO existingLink : linksAsParentId){
					newLink = new DocumentLinkDTO();
					newLink.setParentDocId(newDocId);
					newLink.setLinkedDocId(existingLink.getLinkedDocId());
					newLink.setLinkType(existingLink.getLinkType());
					ApplicationUtilities.populateCommonDetails(newLink, true);
					linksForRenewedDoc.add(newLink);
				}
			}
			List<DocumentLinkDTO> linkedAsChild = comDao.loadLinkedDocument(docIdToBeRenewed);
			if(null != linkedAsChild && linkedAsChild.size() > 0){
				for(DocumentLinkDTO existingLink : linkedAsChild){
					if(!existingLink.getLinkType().equals(DocLinkType.General))
						continue;
					newLink = new DocumentLinkDTO();
					newLink.setParentDocId(existingLink.getParentDocId());
					newLink.setLinkedDocId(newDocId);
					newLink.setLinkType(existingLink.getLinkType());
					ApplicationUtilities.populateCommonDetails(newLink, true);
					linksForRenewedDoc.add(newLink);
				}
			}
			
			documentDAO.saveDocumentLinking(linksForRenewedDoc);
			if(deleteLinksForSource && null != linkedAsChild && linkedAsChild.size() > 0)
				documentDAO.deleteDocumentLinking(linkedAsChild);
			
		}catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
	}
	
	public void copyAuthorisedSignatory(long sourceDocId,long destDocId,boolean deleteSource) {
		try{
			List<DocumentAuthSignatoryDTO> existingSignatoryList = workflowDao.getDocumentAuthSignatory(sourceDocId);
			if(null != existingSignatoryList && existingSignatoryList.size() > 0){
				List<DocumentAuthSignatoryDTO> newSignatoryList = new ArrayList<DocumentAuthSignatoryDTO>();
				for(DocumentAuthSignatoryDTO existingAuthSignatoryDTO : existingSignatoryList){
					DocumentAuthSignatoryDTO newDTO = new DocumentAuthSignatoryDTO();
					BeanUtils.copyProperties(existingAuthSignatoryDTO, newDTO);
					newDTO.setDocId(destDocId);
					newSignatoryList.add(newDTO);
				}
				workflowDao.saveAuthSignatory(newSignatoryList);
				
				if(deleteSource){
					//delete existing
					documentDAO.deleteAuthSignatoryLinking(existingSignatoryList);
				}
					
			}
		}catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
	}
}




/*amit.gupta@ilmp-tech.com*/